博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces Round #540 (Div. 3)题解
阅读量:4948 次
发布时间:2019-06-11

本文共 7022 字,大约阅读时间需要 23 分钟。

题目链接:

  

A题:

题意:

  q次查询,给你一个n,要你用1和2来凑出n,1的花费为a,2的花费为b,求花费的最小值。

思路:

  我们知道当2*a<=b时全用1来肯定是最优的,当2*a>b时,若n为奇数就是1个1其他全是2,若n为偶数就全都是2这样是最优的。

代码实现如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 using namespace std;17 18 typedef long long LL;19 typedef pair
pLL;20 typedef pair
pLi;21 typedef pair
pil;;22 typedef pair
pii;23 typedef unsigned long long uLL;24 25 #define lson rt<<126 #define rson rt<<1|127 #define lowbit(x) x&(-x)28 #define name2str(name) (#name)29 #define bug printf("*********\n")30 #define debug(x) cout<<#x"=["<
<<"]" <
View Code

 

B题:

题意:

  给你n个数,要你去掉一个数,然后剩余的n-1个数保持相对顺序不变,问有多少种方案使得剩下的数中奇数项的和等于偶数项的和。

思路:

  我们知道去掉一个数后对前面的数的位置的奇偶性不会产生影响,后面的数的位置的奇偶性变为对立的,因此我们只需要求下奇数项和偶数项的前缀和即可。

代码实现如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 using namespace std;17 18 typedef long long LL;19 typedef pair
pLL;20 typedef pair
pLi;21 typedef pair
pil;;22 typedef pair
pii;23 typedef unsigned long long uLL;24 25 #define lson rt<<126 #define rson rt<<1|127 #define lowbit(x) x&(-x)28 #define name2str(name) (#name)29 #define bug printf("*********\n")30 #define debug(x) cout<<#x"=["<
<<"]" <
View Code

 

C题:

题意:

  给你n*n个数要你构建一个每行每列都是回文的矩阵。

思路:

  模拟即可。

代码实现如下:

 

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 using namespace std; 17 18 typedef long long LL; 19 typedef pair
pLL; 20 typedef pair
pLi; 21 typedef pair
pil;; 22 typedef pair
pii; 23 typedef unsigned long long uLL; 24 25 #define lson rt<<1 26 #define rson rt<<1|1 27 #define lowbit(x) x&(-x) 28 #define name2str(name) (#name) 29 #define bug printf("*********\n") 30 #define debug(x) cout<<#x"=["<
<<"]" <
(n-1) || (num1 > 0 && num3 > 0) || (num1 == 0 && num3 != 1) || (num3 == 0 && num1 != 1)) return printf("NO\n") * 0; 72 for(int i = 1; i <= 1000; i++) { 73 if(cnt[i] % 4 == 1 || cnt[i] % 4 == 3) { 74 mp[n/2+1][n/2+1] = i; 75 cnt[i]--; 76 break; 77 } 78 } 79 int pp = 1; 80 for(int i = 1; i <= n / 2; i++) { 81 for(int j = 1; j <= n / 2; j++) { 82 while(cnt[pp] < 4) pp++; 83 mp[i][j] = mp[i][n-j+1] = mp[n-i+1][j] = mp[n-i+1][n-j+1] = pp; 84 cnt[pp] -= 4; 85 } 86 } 87 pp = 1; 88 for(int i = 1; i <= n / 2; i++) { 89 while(cnt[pp] == 0) { 90 pp++; 91 if(pp > 1000) return printf("NO\n") * 0; 92 } 93 mp[i][n/2+1] = mp[n-i+1][n/2+1] = pp; 94 cnt[pp] -= 2; 95 } 96 for(int i = 1; i <= n / 2; i++) { 97 while(cnt[pp] < 2) { 98 pp++; 99 if(pp > 1000) return printf("NO\n") * 0;100 }101 if(pp > 1000) return printf("NO\n") * 0;102 mp[n/2+1][i] = mp[n/2+1][n-i+1] = pp;103 cnt[pp] -= 2;104 }105 }106 printf("YES\n");107 for(int i = 1; i <= n; i++) {108 for(int j = 1; j <= n; j++) {109 printf("%d ", mp[i][j]);110 }111 printf("\n");112 }113 return 0;114 }
View Code

 

 

 

D题:

题意:

  有n杯咖啡,m页作业,每杯咖啡的权值为ai,假如你某一天喝了k杯咖啡那么你写的作业页数为a1,a2-1,a3-2……这里的1,2,3指当天喝的顺序而非原序列的下标,要你用最少的天数写完作业。

思路:

  先将ai从大到小排序,二分天数,然后把所有会产生正贡献的咖啡求和,与m比较即可。

代码实现如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 using namespace std;17 18 typedef long long LL;19 typedef pair
pLL;20 typedef pair
pLi;21 typedef pair
pil;;22 typedef pair
pii;23 typedef unsigned long long uLL;24 25 #define lson rt<<126 #define rson rt<<1|127 #define lowbit(x) x&(-x)28 #define name2str(name) (#name)29 #define bug printf("*********\n")30 #define debug(x) cout<<#x"=["<
<<"]" <
0) {53 sum += a[i] - tmp;54 } else {55 break;56 }57 }58 return sum >= m;59 }60 61 bool cmp(int a, int b) {62 return a > b;63 }64 65 int main(){66 scanf("%d%d", &n, &m);67 LL sum = 0;68 for(int i = 1; i <= n; i++) {69 scanf("%d", &a[i]);70 sum += a[i];71 }72 sort(a + 1, a + n + 1, cmp);73 if(sum < m) {74 return printf("-1\n") * 0;75 }76 int ub = inf, lb = 1, mid, ans = 0;77 while(ub >= lb) {78 mid = (ub + lb) >> 1;79 if(check(mid)) {80 ub = mid - 1;81 ans = mid;82 } else {83 lb = mid + 1;84 }85 }86 printf("%d\n", ans);87 return 0;88 }
View Code

E题:

题意:

  给你n和k,要你构建n对数,假设第i对为ai,bi,第j对为aj,bj,需满足一下条件:

  1. ai!=bi;
  2. ai==aj与bi==bj不能同时成立;
  3. 若j==i+1时,ai!=aj且bi!=bj。

思路:

  第一个数一直是1~k的循环,第二个数则是2~k~1,3~k~2,4~k~2这样循环,我们知道满足题意的总排列对数只有k*(k-1)种(第一位放置方法有k种选择,第二位也有k种,故总的排列方法是k*k,其中只有1-1,2-2这种是不满足要求的),因此当n>k*(k-1)时输出NO。

代码实现如下:

1 #include
2 using namespace std; 3 int n,k; 4 pair
ans[200007]; 5 int main(){ 6 scanf("%d%d",&n,&k); 7 if(n>1LL*k*(k-1)) return puts("NO")*0; 8 int a=2,x=1,y=2; 9 for(int i = 1; i<=n;i++){10 ans[i]={x,y};11 x++,y++;12 if(x>k) x = 1;13 if(y>k) y =1;14 if(y==a) {15 a++;16 if(a>k) a=1;17 y = a;18 }19 }20 puts("YES");21 for(int i =1;i<=n;i++){22 printf("%d %d\n",ans[i].first,ans[i].second);23 }24 return 0;25 }
View Code

F1题:

题意:

  给你一棵树,每个结点的颜色可以是0,1,2,要你删除一条边使得得到的两个联通块内不能同时出现1和2。

思路:

  dfs记一下子树中的1和2的个数与总的1和2的个数比较即可。

代码实现如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 using namespace std;17 18 typedef long long LL;19 typedef pair
pLL;20 typedef pair
pLi;21 typedef pair
pil;;22 typedef pair
pii;23 typedef unsigned long long uLL;24 25 #define lson rt<<126 #define rson rt<<1|127 #define lowbit(x) x&(-x)28 #define name2str(name) (#name)29 #define bug printf("*********\n")30 #define debug(x) cout<<#x"=["<
<<"]" <
G[maxn];45 46 void dfs(int u, int p) {47 if(a[u] == 1) sum1[u]++;48 else if(a[u] == 2) sum2[u]++;49 for(int i = 0; i < (int)G[u].size(); i++) {50 int v = G[u][i];51 if(v == p) continue;52 dfs(v, u);53 if((sum1[v] == num1 && sum2[v] == 0) || (sum2[v] == num2 && sum1[v] == 0)) ans++;54 sum1[u] += sum1[v], sum2[u] += sum2[v];55 }56 }57 58 int main(){59 scanf("%d", &n);60 for(int i = 1; i <= n; i++) {61 scanf("%d", &a[i]);62 if(a[i] == 1) num1++;63 else if(a[i] == 2) num2++;64 }65 for(int i = 1; i < n; i++) {66 scanf("%d%d", &u, &v);67 G[u].push_back(v);68 G[v].push_back(u);69 }70 dfs(1, 0);71 printf("%lld\n", ans);72 return 0;73 }
View Code

 

转载于:https://www.cnblogs.com/Dillonh/p/10405917.html

你可能感兴趣的文章
单变量微积分笔记23——部分分式
查看>>
Verilog_Day3
查看>>
Entity Framework Code First添加修改及删除外键关联实体
查看>>
C#中控件的CheckState和Checked属性区别?
查看>>
(转载)柯里化函数应用
查看>>
Codeforces Round #341 (Div. 2)
查看>>
【代码笔记】iOS-自定义开关
查看>>
观察者设计模式
查看>>
把nginx加入系统服务!!
查看>>
sql事务(Transaction)用法介绍及回滚实例
查看>>
C++各大有名库的介绍
查看>>
35-02单页面上拉加载例子
查看>>
你从哪里来
查看>>
Nginx反向代理配置
查看>>
获取url中的参数(微信开发)
查看>>
【原创】.Net 微信 JS-SDK图片、语音上传接口的实现(MVC)-(一 、上传图片)...
查看>>
PHP扩展
查看>>
【转】Scala片段 1:Folding
查看>>
Redis 持久化
查看>>
BZOJ 1579: [Usaco2009 Feb]Revamping Trails 道路升级( 最短路 )
查看>>