标签:close top efi 二分答案 tac push text span char
2015的题比2014丧多了。
T1——神奇的幻方——然而T1还是挺简单的——简单模拟。
#include<iostream> #include<cstdio> using namespace std; int n,a[50][50],x,y; int main() { scanf("%d",&n); x=1;y=(n+1)>>1;a[x][y]=1; for(int i=2;i<=n*n;i++){ if(x==1&&y!=n)x=n,y++; else if(y==n&&x!=1)y=1,x--; else if(x==1&&y==n)x++; else if(x!=1&&y!=n){ if(!a[x-1][y+1])x--,y++; else x++; } a[x][y]=i; } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++) printf("%d ",a[i][j]); puts(""); } return 0; }
T2——信息传递——这题就是找一个最小环——至于做法,我用强连通分量做。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<stack> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>‘9‘||c<‘0‘){if(c==‘-‘)t=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){num=num*10+c-‘0‘;c=getchar();} return num*t; } const int N=200010,inf=1e9; int n,g[N],dfn[N],low[N],t=0,cnt=0,biao[N],ans=1e9; stack<int> s; void dfs(int x){ dfn[x]=low[x]=++t;s.push(x); int y=g[x]; if(!dfn[y]){dfs(y);low[x]=min(low[x],low[y]);} else if(!biao[y])low[x]=min(low[x],dfn[y]); if(low[x]==dfn[x]){ int st=-1,tmp=0;cnt++; while(st!=x){ st=s.top();s.pop(); biao[st]=cnt;tmp++; } if(tmp!=1)ans=min(tmp,ans); } } int main() { n=read(); for(int i=1;i<=n;i++)g[i]=read(); for(int i=1;i<=n;i++) if(!dfn[i])dfs(i); printf("%d\n",ans); return 0; }
T3——斗地主——哎——看了半天不明白是怎么dfs+贪心的。
T4——跳石头——贪心+二分答案。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; inline int read(){ int num=0,t=1;char c=getchar(); while(c>‘9‘||c<‘0‘){if(c==‘-‘)t=-1;c=getchar();} while(c<=‘9‘&&c>=‘0‘){num=(num<<1)+(num<<3)+c-‘0‘;c=getchar();} return num*t; } int L,n,m,a[50010]; int check(int num){ int la=0,cnt=0; for(int i=1;i<=n+1;i++) if(a[i]-la<num)cnt++; else la=a[i]; return cnt; } int ef(){ int l=1,r=L,mid,ans; while(l<=r){ mid=(l+r)>>1; int tmp=check(mid); if(tmp<=m){ans=mid;l=mid+1;} else r=mid-1; } return ans; } int main() { L=read();n=read();m=read();a[n+1]=L; for(int i=1;i<=n;i++)a[i]=read(); printf("%d\n",ef()); return 0; }
T5——字串——动态规划!!
f[i][j][k][l]表示字符串a的前i个字符和字符串b的前j个字符用了k个子串,l=1表示a字符串的第i个字符必须被选出,l=0表示a字符串的第i个字符不能被选出。
为了优化空间,用滚动数组。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>‘9‘||c<‘0‘){if(c==‘-‘)t=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){num=num*10+c-‘0‘;c=getchar();} return num*t; } #define min(a,b) (a<b?a:b) const int N=1010,M=210,mod=1e9+7; int n,m,ki,f[2][M][M][2]; char a[N],b[M]; int main() { n=read();m=read();ki=read(); scanf("%s%s",a+1,b+1); f[0][0][0][0]=f[1][0][0][0]=1; for(int i=1;i<=n;i++){ int t=i&1; for(int j=1;j<=min(i,m);j++) for(int k=1;k<=min(j,ki);k++){ f[t][j][k][1]=f[t][j][k][0]=0; f[t][j][k][0]=(f[t^1][j][k][0]+f[t^1][j][k][1])%mod; if(a[i]==b[j]){ f[t][j][k][1]=( f[t^1][j-1][k-1][1]+ f[t^1][j-1][k-1][0] )%mod; f[t][j][k][1]=( f[t][j][k][1]+ f[t^1][j-1][k][1] )%mod; } } } printf("%d\n",(f[n&1][m][ki][0]+f[n&1][m][ki][1])%mod); return 0; }
至于T6——不是很懂、、、、
本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。
标签:close top efi 二分答案 tac push text span char
原文地址:http://www.cnblogs.com/Yzyet/p/7500344.html