A - Score
水
#include<bits/stdc++.h> using namespace std; int main(){ int n; cin>>n; while(n--){ int sum=0; string s; cin>>s; int len=s.size(); int tmp=0; for(int i=0;i<len;i++){ if(s[i]=='O')sum+=tmp,tmp++; else { sum+=tmp; tmp=0; } } sum+=tmp; cout<<sum<<endl; } return 0; }
B - Tetrahedron
题意:四面体,从D走n-1步回到D点,问你有多少种走法,数据量1e7;
标准错误解法:广搜:
#include<iostream> #include<queue> using namespace std; #define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++) #define per(i,j,k) for(int i=(int)k;i>=(int)j;i--) #define pb push_back #define pf push_front #define fi first #define se second 11 typedef long long ll; typedef unsigned long long ull; typedef long double ldb; typedef double db; // const db PI=acos(-1.0); const ll INF=0x3f3f3f3f3f3f3f3fLL; const int inf=0x3f3f3f3f;//0x7fffffff; const double eps=1e-9; const ll MOD=1e9+7; const int maxn=1e3+5; ll n,ans; struct node{int id;ll step;node(int x,ll y){id=x,step=y;}}; void bfs(){ queue<node>Q; Q.push(node(4,0)); while(!Q.empty()){ node tmp=Q.front(); Q.pop(); if(tmp.step==n&&tmp.id==4){ ans++; } if(tmp.id==1&&tmp.step<n){ int t=(tmp.step+1)%MOD; Q.push(node(2,t)); Q.push(node(3,t)); Q.push(node(4,t)); } if(tmp.id==2&&tmp.step<n){ int t=(tmp.step+1)%MOD; Q.push(node(3,t)); Q.push(node(4,t)); Q.push(node(1,t)); } if(tmp.id==3&&tmp.step<n){ int t=(tmp.step+1)%MOD; Q.push(node(1,t)); Q.push(node(2,t)); Q.push(node(4,t)); } if(tmp.id==4&&tmp.step<n){ int t=(tmp.step+1)%MOD; Q.push(node(1,t)); Q.push(node(2,t)); Q.push(node(3,t)); } } } int main(){ cin>>n; ans=0; bfs(); cout<<ans<<endl; // system("pause"); return 0; }
fyh正解:dp;
这个很像dp,定义状态: dp(i,j)为走i步,到了 j 点 ;
每走一步都受前面状态影响:转移方程为: dp[i][j]+=dp[i-1][k];
#include<bits/stdc++.h> using namespace std; #define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++) #define per(i,j,k) for(int i=(int)k;i>=(int)j;i--) #define pb push_back #define pf push_front #define fi first #define se second 11 typedef long long ll; typedef unsigned long long ull; typedef long double ldb; typedef double db; // const db PI=acos(-1.0); const ll INF=0x3f3f3f3f3f3f3f3fLL; const int inf=0x3f3f3f3f;//0x7fffffff; const double eps=1e-9; const ll MOD=1e9+7; const int maxn=1e7+5; int dp[maxn][4]; int main(){ int n; cin>>n; dp[0][0]=0; dp[1][1]=1; dp[1][2]=1; dp[1][3]=1; for(int i=2;i<=n;i++) for(int j=0;j<=3;j++){ for(int k=0;k<=3;k++){ if(j==k)continue; dp[i][j]+=dp[i-1][k]; // else dp[i][j]= dp[i][j]%=MOD; } } cout<<dp[n][0]<<endl; return 0; }
G - Jumping Jack
题意:给你一个x 小于1e9;问你从0走到x要走几步;
解法:这题本来想广搜,问题和抓住那头牛很像,但数据量太大,搜索爆炸,本来想优化,但怎么搞呢?
正解:你想他 想左走向右走,在第n步,本来走 n+n+1,但现在变成了 -n+n+1,相差 2*n 步,这是个微调;
那你直接一直跳,超过的步数如果是偶数,就n/2步,是奇数肯定不能这样微调的,只能继续走。
和抓住这头牛 不一样,这题向左再向右是有策略的 ,可以微调的;
#include<bits/stdc++.h> using namespace std; int main(){ int x; cin>>x; if(x<0)x=-x; int sum=0; int i; for(i=0; ;i++){ sum+=i; if(sum==x)break; else if(sum>x&&(sum-x)%2==0)break; } cout<<i<<endl; return 0; }
D - Ehab and a 2-operation task
这题傻眼了:
题意:让你对一个序列进行n+1次操作。怎么把它变成严格单增的序列;
做法:先模1,这样全都清空为0,然后都变成2*n,一步步取余,最后就是单增得了;
但是为什么不是2n呢,手算一下就知道了,后面会重合;
#include<bits/stdc++.h> using namespace std; int main(){ int n,k; cin>>n; for(int i=1;i<=n;i++)scanf("%d",&k); printf("%d ",n+1); printf("2 %d 1 ",n); printf("1 %d %d ",n,2*n); for(int i=1;i<n;i++){ printf("2 %d %d ",i,2*n-i); } return 0; }
C - Permute Digits
题意:给你a,b,让你把a变成小于b的最大数。
解法:开始大模拟:
但一直wa,后来又mqf给了这样一组数据;3517 3503,
开始没有考虑取不到解的情况。
就是你一直取大于小于的,如果后面无解呢?只能回退,让前面的变小。
这点没考虑到。
然后模拟一直崩,有时间再来调一下。
错误解法:
#pragma comment(linker, "/STACK:102400000,102400000") #include<bits/stdc++.h> using namespace std; #define pb push_back #define pf push_front #define fi first #define se second 11 typedef long long ll; typedef unsigned long long ull; typedef long double ldb; typedef double db; const db PI=acos(-1.0); const ll INF=0x3f3f3f3f3f3f3f3fLL; const int inf=0x3f3f3f3f;//0x7fffffff; const double eps=1e-9; const ll MOD=1e9+7; const int maxn=1e7+5; int vis[20]; bool flag; int find(int x){ for(int j=9;j>=0;j--){ if(!flag&&vis[j]>0&&j<=x){ if(j<x)flag=1; vis[j]--; return j; } else if(flag&&vis[j]>0){ vis[j]--; return j; } } return -1; } int main(){ flag=0; string sa,sb; cin>>sa>>sb; if(sa.size()<sb.size()){ sort(sa.begin(),sa.end()); int len=sa.size(); for(int i=len-1;i>=0;i--)//逆序输出 cout<<sa[i]; } else { memset(vis,0,sizeof vis); // vector<int>ans; int ans[20]; int len=sa.size(); for(int i=0;i<len;i++){ int tmp=sa[i]-'0'; vis[tmp]++; } len=sb.size(); int i; for( i=0;i<len;i++){ int t=sb[i]-'0'; int tmp=find(t); if(tmp!=-1)ans[i]=tmp; else { while(tmp==-1){ i--; vis[ans[i]]++; t=sb[i]-'0'-1; tmp=find(t); } ans[i]=tmp; vis[tmp]--; flag=1; } } // int p=0; // while(ans[p]==0&&p!=len-1)p++; for(int i=0;i<len;i++) cout<<ans[i]; } return 0; } // 1753
正确解法:用string里的大小比较,默认最小,然后每次从最高位开始找,能替换就替换掉。
如果替换后大于b,就退回来,确实很巧妙。
#include<bits/stdc++.h> using namespace std; int main(){ string t,a,b; cin>>a>>b; sort(a.begin(),a.end()); if(a.size()<b.size()){ reverse(a.begin(),a.end()); } else { int len=a.size(); int L,R; for(L=0;L<len;L++){ R=len-1; t=a; while(L<R){ swap(a[L],a[R--]); sort(a.begin()+L+1,a.end()); if(a>b)a=t; else break; } } } cout<<a<<endl; return 0; }
英语吓得不轻;
#include<bits/stdc++.h> using namespace std; int main(){ int suma=0,sumb=0,oka=0,okb=0; int n,t,x,y; cin>>n; while(n--){ cin>>t>>x>>y; if(t==1){ suma+=10; oka+=x; } else { sumb+=10; okb+=x; } } if(oka>=suma/2)cout<<"LIVE"<<endl; else cout<<"DEAD"<<endl; if(okb>=sumb/2)cout<<"LIVE"<<endl; else cout<<"DEAD"<<endl; return 0; }
F - Squares
看清题意就好了,站在边上的不算属于这个空间;
#include<bits/stdc++.h> using namespace std; int a[100]; int main(){ int n,k; cin>>n>>k; for(int i=1;i<=n;i++)scanf("%d",&a[i]); sort(a+1,a+1+n); if(k>n)cout<<"-1"<<endl; else { cout<<a[n-k+1]<<" "<<a[n-k+1]<<endl; } return 0; }