/*
hnust各题的解题思路:
1002冠军:
题目要求确保某一位你的朋友成为冠军,那么只要用各个人的比赛情况建立一个有向图
,如果a胜b,就建立一点a->b的边,最后用所有朋友点遍历一次全图,如果所有的点都
被遍历了,那么冠军一定在朋友中,至于是哪一个朋友我们不知道,但是题目要求只要
一个朋友是冠军就可以了,所以此法可解;
1003套盒子:
这题是区域赛的一个原题型,可转化为一个匹配问题,设盒子套盒子为一个匹配过程,
因为一个盒子最多只能套一个盒子,所以盒子的匹配容量为1,因为最底下的盒子套不
到一个盒子,所以在所有的盒子匹配完后,统计盒子容量为0的个数即为这题的解;
1005密钥:
一个模拟题,直接用最长的字符串枚举密钥的长度就可以了,从小枚举到大,如果一旦
符合,即为最短的可能密钥;这题的关键在于用最长的字符串来枚举密钥,而不是用最
短的,因为有可能最短的枚举完了,都不符合长串的要求,可是因为当密钥大于明文的
长度时,多余的部分是不起作用的,所以可能用更长的密钥其实是可以的,以致有可能
造成误解;
1006做面包:
二维背包问题,对以前的均分两份的一维背包进行扩展,这里用F[a][b]表示在第一个
烤箱里用了a分钟,在第二个烤箱里用了b分钟,那么自然第三个烤箱里就用了sum-a-b
分钟,就在就对a,b在进行背包,因为sum<=1200,ti<=30,所以a,b<=430,因为取超过3
分之一后没意义,后面就是状态转移了,如下:
if(F[a][b]==1)
{
F[a+ti][b]=1;
F[a][b+ti]=1;
}
转移的时间复杂度为O(40*430*430);
最后对所有的F[a][b]等于1的进行遍历一遍,取最优值就可以了;
1010最少步 :
区间记忆化搜索:
枚举所有的区间翻转(ps:也有可能这个并不需翻转,那么自然这个区间的最小步自然就
为0了),并记忆每个区间的最小步,最后的dfs(0,len-1)的最小步即为题解,时间
复杂度O(n^3);
各题的代码如下:
*/
1002:
#include<stdio.h> #include<queue> #include<string.h> using namespace std; struct edge { int to,next; }edge[210000]; int ant,head[110000]; void add(int a,int b) { edge[ant].to=b; edge[ant].next=head[a]; head[a]=ant++; } int frd[110000],vis[110000]; void bfs(int root) { int i,to; queue <int> que; que.push(root); vis[root]=1; while(!que.empty()) { int u=que.front(); que.pop(); for(i=head[u];i!=-1;i=edge[i].next) { to=edge[i].to; if(!vis[to]) { vis[to]=1; que.push(to); } } } } int main() { int n,k,m,i,a,b; while(scanf("%d%d%d",&n,&k,&m),n+k+m) { ant=0; memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); for(i=1;i<=k;i++) scanf("%d",&frd[i]); for(i=1;i<=m;i++) { scanf("%d%d",&a,&b); add(a,b); } for(i=1;i<=k;i++) bfs(frd[i]); for(i=1;i<=n;i++) if(!vis[i]) break; puts(i==n+1?"yes":"no"); } return 0; }
1003:
#include<stdio.h> #include<string.h> int vis[510],pre[510]; struct node { int x,y,h; }num[510]; int n; int judge(int x,int y) { return num[x].x>num[y].x&&num[x].y>num[y].y&&num[x].h>num[y].h; } int find(int x) { int i; for(i=1;i<=n;i++) { if(x!=i&&!vis[i]&&judge(x,i)) { vis[i]=1; if(!pre[i]||find(pre[i])) { pre[i]=x; return 1; } } } return 0; } int main() { int i,sum; while(scanf("%d",&n),n) { for(i=1;i<=n;i++) scanf("%d%d%d",&num[i].x,&num[i].y,&num[i].h); sum=0; memset(pre,0,sizeof(pre)); for(i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); sum+=find(i); } printf("%d\n",n-sum); } return 0; }
1005:
#include<stdio.h> #include<string.h> char str[110],tem[110],std[110]; char str1[110][110],str2[110][110]; int judge(char *s1,char *s2,char *s3) { int i,len=strlen(s2),j,k; for(i=0,j=0;i<len;i++) { if(s1[j]) { tem[j]=s2[i]+s1[j]-'A'; if(tem[j]>'Z')tem[j]-=26; if(tem[j]!=s3[i])return 0; j++; } else { for(k=0;k<j;k++) s1[k]=tem[k]; j=0; i--; } } return 1; } int main() { int n,len,i,k,j,flag,t,g; while(scanf("%d",&n),n) { k=0; for(i=1;i<=n;i++) { scanf("%s%s",str1[i],str2[i]); len=strlen(str1[i]); if(len>k) { flag=i; k=len; } } for(i=1;i<=k;i++) { for(j=0;j<i;j++) { std[j]=str2[flag][j]-str1[flag][j]+'A'; if(std[j]<'A') std[j]+=26; } std[i]=0; for(g=0;g<i;g++) str[g]=std[g]; str[i]=0; if(judge(str,str1[flag],str2[flag])) t=1; else t=0; for(j=1;t&&j<=n;j++) { for(g=0;g<i;g++) str[g]=std[g]; str[i]=0; if(!judge(str,str1[j],str2[j])) t=0; } if(t==1) break; } if(i<=k) { printf("%s\n",std); } else puts("Impossible"); } return 0; }
1006:
#include<stdio.h> #include<string.h> int dp[520][520],sum,num[45]; int main() { int n,i,k,j,v; while(scanf("%d",&n),n) { sum=0; for(i=1;i<=n;i++) { scanf("%d",&num[i]); sum+=num[i]; } memset(dp,0,sizeof(dp)); dp[0][0]=1; for(i=1;i<=n;i++) { for(j=sum/3+50;j>=0;j--) { for(k=sum/3+50;k>=0;k--) { if(dp[j][k]) { dp[j+num[i]][k]=1; dp[j][k+num[i]]=1; } } } } k=1200; for(i=0;i<=sum/3+50;i++) { for(j=0;j<=sum/3+50;j++) { if(dp[i][j]) { v=i; if(j>v)v=j; if(sum-j-i>v)v=sum-i-j; if(v<k)k=v; } } } printf("%d\n",k); } return 0; }
1010:
#include<stdio.h> #include<string.h> char s1[210],s2[210]; int dp[210][210]; int Min(int a,int b){return a<b?a:b;} int dfs(int s,int t) { char bef; int i,a,b; if(s>t)return 0; if(dp[s][t]!=-1) return dp[s][t]; for(i=s;i<=t;i++) if(s1[i]!=s2[i]) break; if(i<=t) { a=b=0; bef='c'; for(i=s;i<=t;i++) { if(s2[i]!=bef) { if(s2[i]=='A') a++; else b++; } bef=s2[i]; } if(a<b) dp[s][t]=a+1; else dp[s][t]=b+1; for(i=s;i<=t-1;i++) { a=dfs(s,i)+dfs(i+1,t); dp[s][t]=Min(dp[s][t],a); } } else dp[s][t]=0; return dp[s][t]; } int main() { int len,cas; scanf("%d",&cas); while(cas--) { scanf("%s%s",s1,s2); memset(dp,-1,sizeof(dp)); len=strlen(s1); printf("%d\n",dfs(0,len-1)); } return 0; }