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

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
#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

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
#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

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
#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 ;
}

 

转载于:https://www.cnblogs.com/DreamUp/archive/2010/08/11/1797633.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值