/*
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;
}