BestCoder Round 70

惨败,不能再嘲笑别人了,否则自己也会像别人那样倒霉

HDU 5615:http://acm.hdu.edu.cn/showproblem.php?pid=5615

求ax^2+bx+c能否拆成(px+k)(qx+m)的形式

不错的方法,原来的被hack了

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <queue>
 6 #include <vector>
 7 #include <algorithm>
 8 
 9 #define rep(i,a,n) for(int i = a;i < n;i++)
10 #define per(i,n,a) for(int i = n-1;i >=a;i--)
11 #define pb push_back
12 #define VI vector<int>
13 #define QI queue<int>
14 #define log2(N) log10(N)/log10(2)
15 #define eps 1e-8
16 
17 typedef long long ll;
18 
19 using namespace std;
20 
21 
22 int main(){
23     int T;
24     scanf("%d",&T);
25     while(T--){
26         ll a,b,c,d;
27         scanf("%I64d%I64d%I64d",&a,&b,&c);
28         d = b*b - 4*a*c;
29         if(d == (ll)sqrt(d)*(ll)sqrt(d)){
30             puts("YES");
31         }
32         else{
33             puts("NO");
34         }
35     }    
36     return 0;
37 }
View Code

HDU 5616:http://acm.hdu.edu.cn/showproblem.php?pid=5616

01背包,记得要来回两次

另外为了简便用到了操作符或 0|0 = 0, 0|1 = 1, 1|1 = 1

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <queue>
 6 #include <vector>
 7 #include <algorithm>
 8 
 9 #define rep(i,a,n) for(int i = a;i < n;i++)
10 #define per(i,n,a) for(int i = n-1;i >=a;i--)
11 #define pb push_back
12 #define VI vector<int>
13 #define QI queue<int>
14 #define log2(N) log10(N)/log10(2)
15 #define eps 1e-8
16 
17 typedef long long ll;
18 
19 using namespace std;
20 
21 const int N = 20 + 5;
22 const int MAXN = 2000 + 5;
23 int n,sum;
24 int a[N] = {};
25 int dp[MAXN] = {};
26 
27 int main(){
28     int T;
29     scanf("%d",&T);
30     while(T--){
31         sum = 0;
32         scanf("%d",&n);
33         rep(i,0,n){
34             scanf("%d",&a[i]);
35             sum += a[i];
36         }  
37         memset(dp,0,sizeof(dp));
38         dp[0] = 1;
39         rep(i,0,n){
40             per(j,sum+1,a[i]){
41                 dp[j] |= dp[j-a[i]];
42             }
43         }
44         rep(i,0,n){
45             rep(j,0,sum-a[i]+1){
46                 dp[j] |= dp[j+a[i]];
47             }
48         }
49         int z;
50         scanf("%d",&z);
51         while(z--){
52             int s;
53             scanf("%d",&s);
54             if(dp[s]){
55                 printf("YES\n");
56             }
57             else{
58                 printf("NO\n");
59             }
60         }
61     }    
62     return 0;
63 }
View Code

HDU 5617:http://acm.hdu.edu.cn/showproblem.php?pid=5617

学习的是NANOAPE的代码。赶紧记录一下。

写得还是糊里糊涂,希望牛人能再指导一下。

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <queue>
 6 #include <vector>
 7 #include <algorithm>
 8 
 9 #define rep(i,a,n) for(int i = a;i <= n;i++)
10 #define per(i,n,a) for(int i = n;i >= a;i--)
11 #define pb push_back
12 #define VI vector<int>
13 #define QI queue<int>
14 #define log2(N) log10(N)/log10(2)
15 #define eps 1e-8
16 
17 typedef long long ll;
18 
19 using namespace std;
20 
21 const int MOD = 5201314;
22 const int MAXN = 500 + 5;
23 char s[MAXN][MAXN] = {};
24 int n;
25 int dp[2][MAXN][MAXN] = {};    //第一个表示状态,第二个表示j横坐标,第三个表示k横坐标
26 
27 int main(){
28     int T;
29     scanf("%d",&T);
30     while(T--){
31         scanf("%d",&n);
32         rep(i,0,n-1){
33             scanf("%s",s+i);       //s+i相当于s[i]
34         }         
35         memset(dp,0,sizeof(dp));
36         if(s[0][0] != s[n-1][n-1]){      //如果左上角第一个和右下角最后一个不一样,直接输出0
37             puts("0");
38             continue;
39         }   
40         dp[1][1][n] = 1;               //先让起点和终点为1
41         rep(i,2,n){
42             int a = i&1 ;int b = 1 - a;    //可以产生两种状态,0和1
43             rep(j,1,i){
44                 per(k,n,n-i){
45                     if(s[j-1][i-j+1-1] == s[k-1][n-(i-(n-k))+1-1]){     //这步非常关键,估计也看的出来是在比较是否两个字母相同。其中n-(i-(n-k))最难理解,大牛写得更是看不懂,如果是我自己的话这样写就能推理出来了吧^_^
46                         dp[a][j][k] = (dp[b][j][k]+dp[b][j-1][k]+dp[b][j][k+1]+dp[b][j-1][k+1])%MOD;      //分别把前后坐标时候的总数给加起来
47                     } 
48                     else{
49                         dp[a][j][k] = 0;
50                     }
51                 }
52             }
53         }
54         
55         int ans = 0;
56         rep(i,1,n){
57             (ans += dp[n&1][i][i])%=MOD;      //假设分别是从两头开始出发的,当他们的横坐标都是i且相遇的时候的总数
58         }
59         printf("%d\n",ans);
60     } 
61     return 0;
62 }
View Code

 

posted @ 2016-02-01 17:15  syuritsu  阅读(134)  评论(0编辑  收藏  举报