题目连接:
http://codeforces.com/contest/777
A. Shell Game
题意
题解:
6是循环节,判一下奇偶
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define mp(x,y) make_pair(x,y)
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//////////////////////////////////////////////////////////////////////////
const int maxn = 1e5+10;
int main(){
int a[3];
int n = read(),x=read();
mem(a);
a[x] = 1;
n%=6;
if(n==0){
cout << x;
return 0;
}
if(n%2){
for(int i=1; i<=n; i++){
if(i%2){
swap(a[0],a[1]);
}else{
swap(a[1],a[2]);
}
}
}else{
for(int i=1; i<=n; i++){
if(i%2){
swap(a[1],a[2]);
}else{
swap(a[0],a[1]);
}
// cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
}
for(int i=0; i<3; i++){
if(a[i]){
cout << i << endl;
break;
}
}
return 0;
}
B. Game of Credit Cards
题意
n代表信用卡号的长度,两个人,第一个串顺序不能变,第二个串顺序可以任意变,每一位比,谁大谁就赢一次,问 第二个人输的最少 和 赢的最多 的次数
题解:
贪心,
第一个ans:用第二个人最大的数和第一个人比这个数小1的数比,求出赢得和平手的次数res,ans=n-res
第二个ans:也是一样,只是不用求平手的次数了
贪心 真恶心啊
代码一
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define mp(x,y) make_pair(x,y)
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//////////////////////////////////////////////////////////////////////////
const int maxn = 1e3+10;
string s1,s2;
int a[maxn],b[maxn];
int main(){
int n = read();
int res=0;
cin >> s1 >> s2;
for(int i=0; i<n; i++){
a[s1[i]-'0']++;
}
for(int i=0; i<n; i++){
b[s2[i]-'0']++;
}
for(int i=9; i>=0; i--){
int t = min(a[i],b[i]);
res += t;
a[i] -= t, b[i] -= t;
}
for(int i=9; i>=0; i--)
for(int j=i-1; j>=0; j--){
if(b[i] && a[j]) {
res++;
a[j]--; b[i]--;
if(b[i]) i++;
break;
}
}
cout << n-res << endl;
mem(a);
mem(b);
for(int i=0; i<n; i++){
a[s1[i]-'0']++;
}
for(int i=0; i<n; i++){
b[s2[i]-'0']++;
}
res = 0;
for(int i=9; i>=0; i--)
for(int j=i-1; j>=0; j--){
if(b[i] && a[j]) {
res++;
b[i]--; a[j]--;
if(b[i]) i++;
break;
}
}
cout << res << endl;
return 0;
}
代码二
pb写的
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define mp(x,y) make_pair(x,y)
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//////////////////////////////////////////////////////////////////////////
const int maxn = 1e3+10;
int n,a[20],b[20],ans;
char s[1010],s2[1010],s1[1010];
int main(){
scanf("%d%s%s",&n,s,s2);
for(int i=0;i<n;i++)b[s2[i]-'0']++;
memcpy(a,b,sizeof(b));
for(int i=0;i<n;i++){
for(int j=s[i]-'0';j<10;j++)
if(b[j]){b[j]--,s1[i]='0'+j;break;}
if(!s1[i])
for(int j=0;j<10;j++)
if(b[j]){b[j]--,s1[i]='0'+j;break;}
}
for(int i=0;i<n;i++)
if(s[i]>s1[i])ans++;
printf("%d\n",ans);
memset(s1,0,sizeof(s1));
for(int i=0;i<n;i++){
for(int j=s[i]-'0'+1;j<10;j++)
if(a[j]){a[j]--,s1[i]='0'+j;break;}
if(!s1[i])
for(int j=0;j<10;j++)
if(a[j]){b[j]--,s1[i]='0'+j;break;}
}
ans=0;
for(int i=0;i<n;i++)
if(s1[i]>s[i])ans++;
printf("%d",ans);
return 0;
}
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
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define mp(x,y) make_pair(x,y)
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//////////////////////////////////////////////////////////////////////////
const int maxn = 1e5+10;
vector<int> a[maxn],dp[maxn];
int len[maxn];
int main(){
int n,m; cin>>n>>m;
for(int i=1; i<=n; i++){
a[i].resize(m+1);
// dp[i].resize(m+1);
for(int j=1; j<=m; j++){
cin >> a[i][j];
// dp[i][j] = 1;
}
}
for(int i=1; i<=n; i++){
dp[i].resize(m+1,1); // 初始化为1 新姿势
int mx = -1;
for(int j=1; j<=m; j++){
if(i>1){
dp[i][j] += ((a[i][j]>=a[i-1][j]) ? dp[i-1][j] : 0);
}
mx = max(mx,dp[i][j]);
}
len[i] = mx;
}
// for(int i=1; i<=n; i++){
// for(int j=1; j<=m; j++)
// cout << dp[i][j] << " ";
// cout << endl;
// }
int q; cin>>q;
for(int i=1; i<=q; i++){
int le=read(),ri=read();
if(len[ri] >= ri-le+1)
puts("Yes");
else
puts("No");
}
return 0;
}