ZZULI-Summer Training Contest(Six) 解题报告
比赛地址:
http://acm.hdu.edu.cn/diy/contest_show.php?cid=7262
1001 --HDU2203
秒杀型水题
巩固下strcpy strcat strstr函数的应用
1002 --HDU1846
博弈题
最基础的博弈,规律很容易发现的
1003 –HDU1071
简单数学题
设抛物线y=a*x^2+b*x+c,直线y=kx+m。根据给出的三点确定出系数a,b,c,k,m。
然后利用定积分算出面积公式即可。
注意题目给定的P1点保证是抛物线的顶点。
1004 –HDU2986
字符串处理题
锻炼大家的代码能力,这一题要注意精度问题啊。
1005 –HDU1422
简单DP题
大家接触过Max Sum这道题吧,这道题的思路可以借鉴那一个题目!
1006 –HDU1078
DFS+DP
当前状态的值可有搜到状态的最优值来确定,因此为了确定当前状态的最优解,可有深搜先确定子问题的最优解。
1007 –HDU1068
二分图最大匹配
利用二分图最大匹配确定最大独立集,在这里出是为了让大家今后学习下。
1008 –HDU1403
后缀数组
利用后缀数组求出最长公共前缀数组height数组,由最长公共前缀的定义可知答案就是两个排名相邻的后缀的最长公共前缀,判断一下是否分属于两个串中就OK了!
1009 –HDU1075
字典树
很简单的字典树应用。偷偷告诉你,这一题用STL map也可以水过的……
附上1006,1007,1008题的代码
HDU1078
代码
#include<stdio.h>
int map[101][101];
int dp[101][101];
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int n,k;
int dfs(int x,int y)//深搜方位
{
int i,j,a,b,max=0;
if(dp[x][y])
return dp[x][y];
for(i=1;i<=k;i++)//一次可以跳1至k步
{
for(j=0;j<4;j++)//搜四个方向
{
a=x+dir[j][0]*i;
b=y+dir[j][1]*i;
if(a>=0&&a<n&&b>=0&&b<n && map[a][b]>map[x][y])
{
int tmp=dfs(a,b);//求解子问题
if(max<tmp)//从周围找到最大的数
max=tmp;
}
}
}
dp[x][y]=map[x][y]+max;//本身值加上下一步的最优值
return dp[x][y];
}
int main()
{
int i,j;
while(scanf("%d%d",&n,&k),n+k+2)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&map[i][j]), dp[i][j]=0;
printf("%d\n",dfs(0,0));
}
return 0;
}
HDU1068
代码
#include<stdio.h>
#include<string.h>
#define N 1000
int map[N][N];
int link[N],useif[N];
int n;
int can(int t)
{
int i;
for(i=0;i<n;i++)
{
if(useif[i]==0 && map[t][i])
{
useif[i]=1;
if(link[i]==-1 || can(link[i]))
{
link[i]=t;
return 1;
}
}
}
return 0;
}
int maxmatch()
{
int i,num=0;
memset(link,-1,sizeof(link));
for(i=0;i<n;i++)
{
memset(useif,0,sizeof(useif));
if(can(i))
num++;
}
return num;
}
int main()
{
int i,a,b,t;
while(scanf("%d",&n)!=EOF)
{
memset(map,0,sizeof(map));
for(i=0;i<n;i++)
{
scanf("%d: (%d)",&a,&t);
while(t--)
{
scanf("%d",&b);
map[a][b]=1;
}
}
printf("%d\n",n-maxmatch()/2);
}
return 0;
}
HDU1403 源自looker
代码
#include<stdio.h>
#include<string.h>
#define maxm 200015
#define maxn 200015
int sa[maxn],height[maxn],bar[maxm],Rank[maxn],Rank_f[maxn],Result_s[maxn];
bool cmp(int *r,int a,int b,int len)
{
return r[a] == r[b]&&r[a+len] == r[b+len];
}
void get_sa(int *r,int n)
{
int i,j,p,*rank = Rank,*rank_f = Rank_f,*result_s = Result_s,*t,m = 300;
for (i = 0; i <= m; i++) bar[i] = 0;
for (i = 0; i < n; i++) bar[rank[i] = r[i]]++;
for (i = 0; i< m; i++) bar[i+1] += bar[i];
for (i = n-1; i>= 0; i--) sa[--bar[rank[i]]] = i;
for (j = 1,p = 1; p < n; j *= 2,m = p){
for (p = 0,i = n-j; i < n; i++) result_s[p++] = i;
for (i = 0; i< n; i++) if (sa[i] >= j) result_s[p++] = sa[i] -j;
for (i = 0; i < n; i++) rank_f[i] = rank[result_s[i]];
for (i = 0; i<=m; i++) bar[i] = 0;
for (i = 0; i< n; i++) bar[rank_f[i]]++;
for (i = 0; i< m; i++) bar[i+1] += bar[i];
for (i = n-1; i >= 0; i--) sa[--bar[rank_f[i]]] = result_s[i];
t = result_s; result_s = rank; rank = t;
for (rank[sa[0]] = 0,i = 1,p = 1; i < n; i++)
rank[sa[i]] = cmp(result_s,sa[i],sa[i-1],j)?p-1:p++;
}
}
void get_height(int *r,int n)
{
int i,j,*rank = Rank,len = 0;
for (i = 0; i< n; i++) rank[sa[i]] = i;
height[0] = 0;
for (i = 0; i < n-1; i++){
if (len != 0) len--;
for (j = sa[rank[i] -1]; r[j+len] == r[i+len]; len++);
height[rank[i]] = len;
}
}
void solve(int len,int n)
{
int i,max = 0;
for (i = 3; i < n; i++)
if (height[i] > max)
if ((sa[i] > len && sa[i-1] < len) || (sa[i] < len && sa[i-1] > len))
max = height[i];
printf ("%d\n",max);
}
int main()
{
int i,r[200010];
char str1[100010],str2[100010];
memset(str1,0,sizeof(str1)); memset(str2,0,sizeof(str2));
while (scanf ("%s%s",&str1,&str2) != EOF)
{
int len1 = strlen(str1),len2 = strlen(str2);
for (i = 0; i< len1; i++) r[i] = str1[i]; r[len1++] = '$';
for (i = 0; i< len2; i++) r[i+len1] = str2[i]; r[len1+len2++] = '#';
int len = len1+len2; get_sa(r,len); get_height(r,len);
solve(len1-1,len);
memset(str1,0,sizeof(str1)); memset(str2,0,sizeof(str2));
}
return 0;
}