8月22号的练习:HDU 1196&&HDU 1673&&HDU 1269&&HDU 1841(KMP)&&HDU 1176(数塔问题)

Lowest Bit HDU 1196

非常水的题目:(不解释)

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 using namespace std;
 5 int main()
 6 {
 7     int n,d;
 8     while(scanf("%d",&n)!=EOF&&n)
 9     {
10         d=0;
11         while(1)
12         {
13             if(n%2==0)
14             {
15                 d++;
16                 n=n/2;
17             }
18              else if(n%2)
19             break;
20         }
21         int s=1;
22         for(int i=1;i<=d;i++)
23             s=s*2;
24         if(d==0)
25             printf("1\n");
26         else
27             printf("%d\n",s);
28     }
29 }

Optimal Parking HDU 1673

水题:看懂题意好做(不解释)

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<stdio.h>
 4 using namespace std;
 5 int main()
 6 {
 7     int t,n,d,i;
 8     int a[25];
 9     scanf("%d",&t);
10     while(t--)
11     {
12         scanf("%d",&n);
13         for(i=0;i<n;i++)
14             scanf("%d",&a[i]);
15         sort(a,a+n);
16         d=a[n-1]-a[0];
17         printf("%d\n",2*d);
18     }
19     return 0;
20 }

迷宫城堡  HDU 1269

就是考邻接表:(套模板就行了)

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<stdio.h>
 4 #include<queue>
 5 #include<string.h>
 6 using namespace std;
 7 queue<int> Q;
 8 int vis[1000005],b[1000005],t,pre[1000005];
 9 struct line
10 {
11     int left;
12     int right;
13     int num;
14     int Next;
15 }a[10000005];//邻接表应开足够大!
16 void add(int left,int right,int num)
17 {
18     a[t].left=left;
19     a[t].right=right;
20     a[t].num=num;
21     a[t].Next=pre[left];
22     pre[left]=t++;
23 }
24 int main()
25 {
26     int n,m,left,right,i,j,max1,p,k,d;
27     max1=10000005;
28     while(scanf("%d%d",&n,&m)!=EOF)
29     {
30         if(n==0&&m==0)
31             break;
32         memset(pre,-1,sizeof(pre));
33         t=1;
34         while(m--)
35         {
36             scanf("%d%d",&left,&right);
37             if(left!=right)
38                 add(left,right,1);
39         }
40         d=0;
41         for(i=1;i<=n;i++)
42         {
43         memset(vis,0,sizeof(vis));
44         for(j=1;j<=n;j++)
45             b[j]=max1;
46         b[i]=0;
47         Q.push(i);
48         while(!Q.empty())
49         {
50             p=Q.front();
51             Q.pop();
52             vis[p]=0;
53             for(j=pre[p];j+1;j=a[j].Next)
54             {
55                 k=a[j].right;
56                 if(b[k]>b[p]+a[j].num)
57                 {
58                     b[k]=b[p]+a[j].num;
59                     if(!vis[k])
60                     {
61                         Q.push(k);
62                         vis[k]=1;
63                     }
64                 }
65             }
66         }
67         for(j=1;j<=n;j++)
68             if(b[j]==max1)
69             {
70                 d=1;
71                 break;
72             }
73         if(d==1)
74             break;
75         }
76         if(d==1)
77             printf("No\n");
78         else
79             printf("Yes\n");
80     }
81     return 0;
82 }

Find the Shortest Common Superstring  HDU 1841

简单KMP算法的应用:

主要理解next[]的意义。。。(是在主串中找是否有完全包含模板串的,一定是完全包含!!

不然就符合题意了,找到最后比较的长度!!

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<stdio.h>
 4 #include<string.h>
 5 #include<string>
 6 using namespace std;
 7 int Next[1000005],len1,len2;
 8 char s1[1000005],s2[1000005];
 9 void get_next(char *s,int len)
10 {
11     int i,j;
12     Next[0]=-1;
13     i=0;
14     j=-1;
15     while(i<len-1)
16     {
17         if(j==-1||s[i]==s[j])
18             Next[++i]=++j;
19         else
20             j=Next[j];
21     }
22 }
23 int KMP(char *s1,char *s2)
24 {
25     int i,j;
26     len1=strlen(s1);
27     len2=strlen(s2);
28     get_next(s2,len2);
29     i=-1;
30     j=-1;
31     while(i<len1&&j<len2)
32     {
33         if(j==-1||s1[i]==s2[j])
34             i++,j++;
35         else
36             j=Next[j];
37     }
38     return j;//主要是这里
39 }
40 int main()
41 {
42     int t,a,b;
43     scanf("%d",&t);
44     while(t--)
45     {
46         scanf("%s%s",s1,s2);
47         a=KMP(s1,s2);
48         b=KMP(s2,s1);
49         printf("%d\n",len1+len2-max(a,b));
50     }
51     return 0;
52 }

免费馅饼 HDU 1176

DP:简单的数塔模型。。。

可将所有的时间段和馅饼看成是一个矩阵,时间就是行数,掉馅饼的就是列数,则就是数字三角形问题,

从最底层找一条路径,使得路径上的和最大。

状态转移方程为:dp[i][j]=max(dp[i+1][j-1],dp[i+1][j],dp[i+1][j-1])+pie[i][j]。

pie[i][j]为时间i时在j位置掉的馅饼数目。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<stdio.h>
 4 #include<string.h>
 5 using namespace std;
 6 int a[100005][12],b[100005][12];
 7 int main()
 8 {
 9     int n,m1,i,j,left,right,mid,a1,b1;
10     while(scanf("%d",&n)!=EOF)
11     {
12         if(n==0)
13             break;
14         m1=0;
15         memset(a,0,sizeof(a));
16         memset(b,0,sizeof(b));
17         while(n--)
18         {
19             scanf("%d%d",&a1,&b1);
20             a[b1][a1+1]++;
21             if(b1>m1)
22                 m1=b1;
23         }
24         for(i=1;i<=11;i++)
25             b[m1][i]=a[m1][i];
26         for(i=m1-1;i>=0;i--)
27             for(j=1;j<=11;j++)
28         {
29             left=b[i+1][j]+a[i][j];
30             right=b[i+1][j+1]+a[i][j];
31             mid=b[i+1][j-1]+a[i][j];
32             b[i][j]=max(left,right);
33             b[i][j]=max(b[i][j],mid);
34         }
35         printf("%d\n",b[0][6]);
36     }
37     return 0;
38 }

 

posted on 2013-08-23 20:11  ~~碾压机  阅读(200)  评论(0编辑  收藏  举报