BestCoder Round 70
惨败,不能再嘲笑别人了,否则自己也会像别人那样倒霉
求ax^2+bx+c能否拆成(px+k)(qx+m)的形式
不错的方法,原来的被hack了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
01背包,记得要来回两次
另外为了简便用到了操作符或 0|0 = 0, 0|1 = 1, 1|1 = 1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
学习的是NANOAPE的代码。赶紧记录一下。
写得还是糊里糊涂,希望牛人能再指导一下。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }