Codeforces Round #401 (Div. 2)A B C

本文提供CodeForces 777竞赛中A、B、C三题的题解及代码实现。A题通过分析循环节解决球的位置问题;B题采用贪心算法解决信用卡号比对问题;C题则使用动态规划和前缀和方法来快速响应关于矩阵列的查询。

题目连接:

http://codeforces.com/contest/777

A. Shell Game

题意

题解:

6是循环节,判一下奇偶

代码

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define mem(a) memset(a,0,sizeof(a))
 5 #define mp(x,y) make_pair(x,y)
 6 const int INF = 0x3f3f3f3f;
 7 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 8 inline ll read(){
 9     ll x=0,f=1;char ch=getchar();
10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 //////////////////////////////////////////////////////////////////////////
15 const int maxn = 1e5+10;
16 
17 int main(){
18     int a[3];
19     int n = read(),x=read();
20     mem(a);
21     a[x] = 1;
22 
23     n%=6;
24     if(n==0){
25         cout << x;
26         return 0;
27     }
28     if(n%2){
29         for(int i=1; i<=n; i++){
30             if(i%2){
31                 swap(a[0],a[1]);
32             }else{
33                 swap(a[1],a[2]);
34             }
35         }
36     }else{
37         for(int i=1; i<=n; i++){
38             if(i%2){
39                 swap(a[1],a[2]);
40             }else{
41                 swap(a[0],a[1]);
42             }
43             // cout << a[0] << " " << a[1] << " " << a[2] << endl;
44         }
45     }
46     for(int i=0; i<3; i++){
47         if(a[i]){
48             cout << i << endl;
49             break;
50         }
51     }
52 
53     return 0;
54 }

 

B. Game of Credit Cards

题意

n代表信用卡号的长度,两个人,第一个串顺序不能变,第二个串顺序可以任意变,每一位比,谁大谁就赢一次,问 第二个人输的最少 和 赢的最多 的次数

题解:

贪心,
第一个ans:用第二个人最大的数和第一个人比这个数小1的数比,求出赢得和平手的次数res,ans=n-res
第二个ans:也是一样,只是不用求平手的次数了

贪心 真恶心啊

代码一

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define mem(a) memset(a,0,sizeof(a))
 5 #define mp(x,y) make_pair(x,y)
 6 const int INF = 0x3f3f3f3f;
 7 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 8 inline ll read(){
 9     ll x=0,f=1;char ch=getchar();
10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 //////////////////////////////////////////////////////////////////////////
15 const int maxn = 1e3+10;
16 
17 string s1,s2;
18 int a[maxn],b[maxn];
19 
20 int main(){
21     int n = read();
22     int res=0;
23     cin >> s1 >> s2;
24     for(int i=0; i<n; i++){
25         a[s1[i]-'0']++;
26     }
27     for(int i=0; i<n; i++){
28         b[s2[i]-'0']++;
29     }
30     for(int i=9; i>=0; i--){
31         int t = min(a[i],b[i]);
32         res += t;
33         a[i] -= t, b[i] -= t;
34     }
35 
36     for(int i=9; i>=0; i--)
37         for(int j=i-1; j>=0; j--){
38             if(b[i] && a[j]) {
39                 res++;
40                 a[j]--; b[i]--;
41                 if(b[i]) i++;
42                 break;
43             }
44         }
45     cout << n-res << endl;
46 
47     mem(a);
48     mem(b);
49     for(int i=0; i<n; i++){
50         a[s1[i]-'0']++;
51     }
52     for(int i=0; i<n; i++){
53         b[s2[i]-'0']++;
54     }
55 
56     res = 0;
57     for(int i=9; i>=0; i--)
58         for(int j=i-1; j>=0; j--){
59             if(b[i] && a[j]) {
60                 res++;
61                 b[i]--; a[j]--;
62                 if(b[i]) i++;
63                 break;
64             }
65         }
66 
67     cout << res << endl;
68 
69 
70 
71     return 0;
72 }

 

代码二

pb写的

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define mem(a) memset(a,0,sizeof(a))
 5 #define mp(x,y) make_pair(x,y)
 6 const int INF = 0x3f3f3f3f;
 7 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 8 inline ll read(){
 9     ll x=0,f=1;char ch=getchar();
10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 //////////////////////////////////////////////////////////////////////////
15 const int maxn = 1e3+10;
16 
17 int n,a[20],b[20],ans;
18 char s[1010],s2[1010],s1[1010];
19 int main(){
20     scanf("%d%s%s",&n,s,s2);
21     for(int i=0;i<n;i++)b[s2[i]-'0']++;
22     memcpy(a,b,sizeof(b));
23     for(int i=0;i<n;i++){
24         for(int j=s[i]-'0';j<10;j++)
25             if(b[j]){b[j]--,s1[i]='0'+j;break;}
26         if(!s1[i])
27             for(int j=0;j<10;j++)
28                 if(b[j]){b[j]--,s1[i]='0'+j;break;}
29     }
30     for(int i=0;i<n;i++)
31         if(s[i]>s1[i])ans++;
32     printf("%d\n",ans);
33     memset(s1,0,sizeof(s1));
34     for(int i=0;i<n;i++){
35         for(int j=s[i]-'0'+1;j<10;j++)
36             if(a[j]){a[j]--,s1[i]='0'+j;break;}
37         if(!s1[i])
38             for(int j=0;j<10;j++)
39                 if(a[j]){b[j]--,s1[i]='0'+j;break;}
40     }
41     ans=0;
42     for(int i=0;i<n;i++)
43         if(s1[i]>s[i])ans++;
44     printf("%d",ans);
45     return 0;
46 }

 

C. Alyona and Spreadsheet

题意:

n*m的矩阵,q次询问 le, ri
问是否存在一列 从le到ri 都是非递减的序列

题解:

1 ≤ n·m ≤ 100 000 所以数组开不下,用vector, 输入完m 再resize
dp[i][j]表示第i行第j列向上延伸最多是多少
转移:dp[i][j] += ((a[i][j]>=a[i-1][j]) ? dp[i-1][j] : 0);
然后维护len[i] 表示 第i行的所有列的最大值。
询问的时候 判断一下 len[ri] >= ri-le+1

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define mem(a) memset(a,0,sizeof(a))
 5 #define mp(x,y) make_pair(x,y)
 6 const int INF = 0x3f3f3f3f;
 7 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 8 inline ll read(){
 9     ll x=0,f=1;char ch=getchar();
10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 //////////////////////////////////////////////////////////////////////////
15 const int maxn = 1e5+10;
16 
17 vector<int> a[maxn],dp[maxn];
18 int len[maxn];
19 
20 int main(){
21     int n,m; cin>>n>>m;
22     for(int i=1; i<=n; i++){
23         a[i].resize(m+1);
24         // dp[i].resize(m+1);
25         for(int j=1; j<=m; j++){
26             cin >> a[i][j];
27             // dp[i][j] = 1;
28         }
29     }
30     for(int i=1; i<=n; i++){
31         dp[i].resize(m+1,1); // 初始化为1 新姿势
32         int mx = -1;
33         for(int j=1; j<=m; j++){
34             if(i>1){
35                 dp[i][j] += ((a[i][j]>=a[i-1][j]) ? dp[i-1][j] : 0);
36             }
37             mx = max(mx,dp[i][j]);
38         }
39         len[i] = mx;
40     }
41 
42     // for(int i=1; i<=n; i++){
43     //  for(int j=1; j<=m; j++)
44     //      cout << dp[i][j] << " ";
45     //  cout << endl;
46     // }
47     int q; cin>>q;
48     for(int i=1; i<=q; i++){
49         int le=read(),ri=read();
50         if(len[ri] >= ri-le+1)
51             puts("Yes");
52         else
53             puts("No");
54     }
55 
56 
57     return 0;
58 }

 

转载于:https://www.cnblogs.com/yxg123123/p/6827694.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值