8月13号的练习:POJ 3210&&HDU 4506&&HDU2546&&HDU 1026(注意事项)

Coins POJ 3210

一道考逻辑的题:(感觉就是找规律)

题目意思是:给出n个硬币,无论初始状态怎么样,总有存在一个最小且合适的数m。使其在任何的初始状态翻转m次达到全部向上或全部向下(一次只翻一个硬币)

其实你画几个图会发现:奇数是不可能满足全部可能的!(因为偶数时都出来的步骤可以用一个循环(翻加不翻)状态不变)

之后画几次发现n为偶数时,总有一个状态需要奇数的翻转才能达到全部向上或全部向下!

n为奇数时,需要最大的偶数次翻转就是(m=n-1)的时候。。。

如果感觉只是猜测的话:请用数学归纳法来求证

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 using namespace std;
 5 int main()
 6 {
 7     int n;
 8     while(~scanf("%d",&n)&&n)
 9     {
10         if(n%2)
11             printf("%d\n",n-1);
12         else
13             printf("No Solution!\n");
14     }
15     return 0;
16 }

小明系列故事――师兄帮帮忙 HDU 4506

还是考快速幂的:(还有取模运算)

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<stdio.h>
 4 using namespace std;
 5 int mod=1000000007;
 6 __int64 a[10005];
 7 int main()
 8 {
 9     int T,n,i;
10     __int64 t,k,sq,t1;
11     scanf("%d",&T);
12     while(T--)
13     {
14         scanf("%d%I64d%I64d",&n,&t,&k);
15         for(i=1;i<=n;i++)
16             scanf("%I64d",&a[i]);
17         sq=1;
18         t1=t;
19         while(t1>0)
20         {
21             if(t1%2)
22                 sq=(sq%mod*k)%mod;
23             t1/=2;
24                k=(k%mod*k)%mod;
25         }//快速幂!
26         t=t%n;
27         for(i=n+1-t;i<=n;i++)
28             printf("%I64d ",(a[i]%mod*sq)%mod);//取模运算
29         for(i=1;i<n+1-t;i++)
30         {
31             if(i==n-t)
32                 printf("%I64d\n",(a[i]%mod*sq)%mod);
33             else
34                 printf("%I64d ",(a[i]%mod*sq)%mod);
35         }
36     }
37     return 0;
38 }

饭卡  HDU2546

一道背包的水题:

思路:因为给出每种菜数量为一,且求在钱数一定的情况下使最后剩下的钱最少!(就是个背包)

只是那五元钱要格外进行考虑:

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

Ignatius and the Princess I  HDU 1026

一个bfs+最短路径:

这里看出:Bfs()是同时向外扩散的:那么记录路径的话根据其特点只要每次取最小值就行了:

如:

先把每点定义无穷大:队列里先进一个点,再对四个方向的值进行比较,再对其中一个点四个方向的值进行比较(注意如果有重复地话,那么就要比较此点值的大小)

只要说明与Dfs()的差别:Dfs()是先一个方向走到底,走不过再回到最开始进行下一个方向,那么这样的话,可以求出多条路径

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<stdio.h>
  4 #include<string.h>
  5 #include<queue>
  6 using namespace std;
  7 struct line
  8 {
  9     char c;
 10     int num,prex,prey,x1,y1;
 11 }a[105][105];
 12 int b1[4][2]={0,1,0,-1,1,0,-1,0},max1=100000005;
 13 queue<line> Q;
 14 int n,m;
 15 void output()
 16 {
 17     int x=0,y=0,a1,b1,num=1,i;
 18     if(a[0][0].num!= max1)
 19     {
 20         printf("It takes %d seconds to reach the target position, let me show you the way.\n",a[0][0].num);
 21         while(x!= n-1| y!=m-1)
 22         {
 23             a1=a[x][y].prex;
 24             b1=a[x][y].prey;
 25             if(a[x][y].c!='.')
 26                 for(i=0;i<a[x][y].c - '0';i++)
 27                     printf("%ds:FIGHT AT (%d,%d)\n",num++,x,y);
 28             printf("%ds:(%d,%d)->(%d,%d)\n",num++,x,y,a1,b1);
 29             x=a1; y=b1;
 30         }
 31         if(a[x][y].c!='.')
 32         {
 33             for(i=0;i<a[x][y].c - '0';i++)
 34                 printf("%ds:FIGHT AT (%d,%d)\n",num++,x,y);
 35         }
 36         printf("FINISH\n");
 37     }
 38     else
 39     {
 40         printf("God please help our poor hero.\nFINISH\n");
 41     }
 42 }
 43 void bfs()
 44 {
 45     int fly1,fly2,temp,i;
 46     line b;
 47     a[n-1][m-1].num=0;
 48     if(a[n-1][m-1].c>='1'&&a[n-1][m-1].c<='9')
 49         a[n-1][m-1].num=a[n-1][m-1].c-'0';
 50     Q.push(a[n-1][m-1]);
 51     while(!Q.empty())
 52     {
 53         b=Q.front();
 54         Q.pop();
 55         for(i=0;i<4;i++)
 56         {
 57             fly1=b.x1+b1[i][0];
 58             fly2=b.y1+b1[i][1];
 59         if(fly1>=0&&fly1<n&&fly2>=0&&fly2<m&&a[fly1][fly2].c!='X')
 60         {
 61             if(a[fly1][fly2].c=='.')
 62                 temp=b.num;
 63             else
 64             {
 65                temp=b.num+a[fly1][fly2].c-'0';
 66             }
 67             if(temp+1<a[fly1][fly2].num)//最每次路径进行比较,取最小值
 68             {
 69                 a[fly1][fly2].num=temp+1;
 70                 a[fly1][fly2].prex=b.x1;
 71                 a[fly1][fly2].prey=b.y1;
 72                 Q.push(a[fly1][fly2]);
 73             }
 74         }
 75         }
 76     }
 77     output();
 78 }
 79 int main()
 80 {
 81     int i,j;
 82     while(scanf("%d%d",&n,&m)!=EOF)
 83     {
 84         getchar();//上面有回车键,要储存不要影响下面的输入
 85         for(i=0;i<n;i++)
 86         {
 87              for(j=0;j<m;j++)
 88                     {
 89                         scanf("%c",&a[i][j].c);
 90                         a[i][j].num=max1;
 91                         a[i][j].x1=i;
 92                         a[i][j].y1=j;
 93                         a[i][j].prex=-1;
 94                         a[i][j].prey=-1;
 95                     }
 96              getchar();//每行之后有回车键,不要影响下面的输入
 97         }
 98         bfs();
 99     }
100     return 0;
101 }

 终于搞懂有些题目要加个getchar()了!!!

关于字符的输入:%c的话可以对空行和回车进行输入!

%s的话遇到空行和回车停止!(这时应用get())。

如:

ASDF

ZXCV

A S D F

Z X C V

的区别:

输入空行%c也算进去的!

posted on 2013-08-14 18:46  ~~碾压机  阅读(151)  评论(0编辑  收藏  举报