码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces Round #498 div3

时间:2018-07-18 11:52:14      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:输入   使用   mod   tar   style   one   链式前向星   inf   oid   

A

题目没读, 啥也不会的室友帮我写的。

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const LL mod = 1e9+7;
16 const int N = 1e5+10;
17 
18 int main(){
19     ///Fopen;
20     int a;
21     cin>>a;
22     int b[a];
23     for(int i=0;i<a;i++){
24         cin>>b[i];
25     }
26     for(int i=0;i<a;i++){
27         if(b[i]%2==0) b[i]=b[i]-1;
28     }
29     for(int i=0;i<a;i++){
30         cout<<b[i]<< ;
31     }
32     return 0;
33 }
A

 

B

题意:一共有n个任务,m天内完成,每个任务必须都要完成,并且不能重复完成,还要按顺序完成,每天能获得的利润为当天任务最大的那个利润,现在划分每天完成的任务数量, 来获得最大的总利润。

题解:选出利润最大的m个任务, 然后每天都包含其中一个就好了。

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const LL mod = 1e9+7;
16 const int N = 1e5+10;
17 pll p[N];
18 int vis[N];
19 int main(){
20     ///Fopen;
21     int n, m;
22     scanf("%d%d", &n, &m);
23     for(int i = 1; i <= n; i++){
24         scanf("%d", &p[i].fi);
25         p[i].se = i;
26     }
27     sort(p+1, p+1+n);
28     int ans = 0;
29     for(int i = n; i >= n - m + 1; i--){
30         ans += p[i].fi;
31         vis[p[i].se] = 1;
32     }
33     printf("%d\n", ans);
34     int cnt = 0;
35     for(int i = 1; i <= n; i++){
36         cnt++;
37         if(vis[i]){
38             m--;
39             if(m == 0) cnt += (n-i);
40             printf("%d ", cnt);
41             cnt = 0;
42         }
43     }
44     return 0;
45 }
B

 

C

题意:给你一堆数列,现在将他们分成连续的3堆,可以为空,现在要求第一堆和最后一堆相等的情况下,最大的第一堆值是多少。

题解:左右开始选,左边大了就右边加上一个新的数,右边大了就左边加上一个新的数,每次相等就记录答案。

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const LL mod = 1e9+7;
16 const int N = 2e5+10;
17 LL d[N];
18 int main(){
19     ///Fopen;
20     int n;
21     scanf("%d", &n);
22     for(int i = 1; i <= n; i++)
23         scanf("%I64d", &d[i]);
24     LL sum1 = 0, sum3 = 0;
25     int i = 1, j = n;
26     sum1 = d[1];
27     sum3 = d[n];
28     LL ans = 0;
29     while(i < j){
30         if(sum1 == sum3){
31             ans = sum1;
32             sum1 += d[++i];
33         }
34         else if(sum1 < sum3) sum1 += d[++i];
35         else if(sum1 > sum3) sum3 += d[--j];
36 
37     }
38     cout << ans << endl;
39     return 0;
40 }
C

 

D

题意:给你2个等长的字符串A B,现在可以对于A B串里面的交换对称位置的字符,也可以交换AB同一位置的字符, 然后对于A串还有一个魔法操作就是选择一个位置上的字符,将这个字符改变成其他任意一个字符。现在求先交换字符位置后,要使得这2个串完全相等需要的魔法操作数是多少。

题解:我们可以发现,对于一个位置来说有其他3个位置是对应的,那么我们从前面往后面扫, 如果这一个位置的AB上的字符都对到了, 那么我们就不对这个位置上的字符进行处理, 然后如果不对, 我们看一下A的对称位置上的字符是不是能和B匹配, 如果可以就将A的2个字符交换, 如果不行我们再看看B的对称位置上的字符是不是和改位置上的字符相等, 如果是, 那么交换该位置的A 和 对称位置上的B。

最后我们再看看AB串相同的位置有多少个字符不相等, 就是答案了。

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const LL mod = 1e9+7;
16 const int N = 1e5+10;
17 char a[N], b[N];
18 int main(){
19     ///Fopen;
20     int n;
21     scanf("%d", &n);
22     scanf("%s", a+1);
23     scanf("%s", b+1);
24     for(int i = 1; i <= n; i++){
25         if(a[i] == b[i]) continue;
26         int j = n - i + 1;
27         if(a[j] == b[i]) swap(a[j], a[i]);
28         if(b[j] == b[i]) swap(a[i], b[j]);
29     }
30     int ans = 0;
31     for(int i = 1; i <= n; i++){
32         ans += (a[i] != b[i]);
33     }
34     cout << ans << endl;
35     return 0;
36 }
D

看了一眼好友列表里面的代码, 就我的最简单了, 233。

 

E

题意:一个公司里面有n个员工, 1号员工为Boss, 然后其他n-1个人都有一个直接上级, 然后上级的上级也算上级, 然后每次一个人接到任务, 都会将任务传递给所有下级, 现在有q次询问,输入一个u k

要求输出第u个员工收到命令后, 第k个收到命令的员工的编号是多少, 如果没有第k个收到命令的员工就输出-1。

题解:dfs序,记录一下开始的dfs序和结束的dfs序, 然后每次询问的时候, 判断一下,有没有第k个员工, 如果有用dfs序输出那个员工的编号就是答案了。

注意的就是链式前向星是倒着遍历边的, 所以如果使用链式前向星要换一个顺序建边。

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const LL mod = 1e9+7;
16 const int N = 2e5+10;
17 int in[N], out[N];
18 vector<int> son[N];
19 int ans[N];
20 int tot = 0;
21 void dfs(int u){
22     ans[++tot] = u;
23     in[u] = tot;
24     for(int i = 0; i < son[u].size(); i++)
25         dfs(son[u][i]);
26     out[u] = tot;
27 }
28 int main(){
29     ///Fopen;
30     int n, m, u;
31     scanf("%d%d", &n, &m);
32     for(int i = 2; i <= n; i++){
33         scanf("%d", &u);
34         son[u].pb(i);
35     }
36     dfs(1);
37     int v, k;
38     while(m--){
39         scanf("%d%d", &v, &k);
40         if(out[v] < in[v] + k - 1)
41             printf("-1\n");
42         else{
43             printf("%d\n", ans[in[v]+k-1]);
44         }
45     }
46     return 0;
47 }
E

 

F:

题意:从[1,1] 走到 [n, m] 的位置, 只能朝右和朝下走, 将路过的值都 xor 起来, 最后求到达[n, m]的时候 xor 的值为k的方案数是多少。

题解:如果直接走到n,m的状态数太多, 所以我们将步数对半分, 从[1,1]开始走一半的步数, 从[n,m]开始走剩下的步数, 然后停下来的时候再统计答案。

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 typedef pair<int,int> pll;
14 const int inf = 0x3f3f3f3f;
15 const LL INF = 0x3f3f3f3f3f3f3f3f;
16 const LL mod =  (int)1e9+7;
17 const int N = 25;
18 map<LL, int> mp[N][N];
19 LL a[N][N];
20 int n, m;
21 LL k;
22 void dfs1(int x, int y, int t, LL now){
23     if(t == 0){
24         mp[x][y][now]++;
25         return ;
26     }
27     if(x+1 <= n) dfs1(x+1,y,t-1,now^a[x][y]);
28     if(y+1 <= m) dfs1(x, y+1, t-1, now^a[x][y]);
29 }
30 LL ans = 0;
31 void dfs2(int x, int y, int t, LL now){
32     if(t == 0){
33         ans += mp[x][y][now];
34         return ;
35     }
36     if(x-1) dfs2(x-1,y,t-1,now^a[x-1][y]);
37     if(y-1) dfs2(x,y-1,t-1,now^a[x][y-1]);
38 }
39 int main(){
40     scanf("%d%d%I64d", &n, &m, &k);
41     for(int i = 1; i <= n; i++)
42         for(int j = 1; j <= m; j++)
43             scanf("%I64d", &a[i][j]);
44     int t = n + m - 2;
45     dfs1(1,1,t/2,0);
46     dfs2(n,m,t-t/2,k^a[n][m]);
47     cout << ans << endl;
48     return 0;
49 }
F

 

CodeForces Round #498 div3

标签:输入   使用   mod   tar   style   one   链式前向星   inf   oid   

原文地址:https://www.cnblogs.com/MingSD/p/9328225.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!