BestCoder Round #70

此处有目录↑

HDU-5615 Jam's math problem

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

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Problem Description
Jam has a math problem. He just learned factorization.
He is trying to factorize  ax2+bx+c  into the form of  pqx2+(qk+mp)x+km=(px+k)(qx+m) .
He could only solve the problem in which p,q,m,k are positive numbers.
Please help him determine whether the expression could be factorized with p,q,m,k being postive.
 

Input
The first line is a number  T , means there are  T(1T100)  cases 

Each case has one line,the line has  3  numbers  a,b,c(1a,b,c100000000)
 

Output
You should output the "YES" or "NO".
 

Sample Input
   
   
   
   
2 1 6 5 1 6 4
 

Sample Output
   
   
   
   
YES NO
Hint
The first case turn (x+1)(x+5)=x^2+6∗x+5

题目大意:判断 ax^2+bx+c能都分解成(px+k)(qx+m)的形式,要求p,q,k,m均为正整数

直接无视正整数三个字,被HACK了。

不过终测后都对了。。。

也没注意a,b,c的范围,由于a,b,c均为正整数,所以若能分解因式,则系数均为正整数

#include <cstdio>
#include <cmath>

using namespace std;

long long a,b,c,T,x,xx;

int main() {
    scanf("%I64d",&T);
    while(T--) {
        scanf("%I64d%I64d%I64d",&a,&b,&c);
        x=b*b-4*a*c;
        if(x>=0) {
            xx=sqrt(x);
            if(xx*xx==x) {
                printf("YES\n");
                continue;
            }
        }
        printf("NO\n");
    }
    return 0;
}




HDU-5616 Jam's balance

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

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Problem Description
Jim has a balance and N weights.  (1N20)
The balance can only tell whether things on different side are the same weight.
Weights can be put on left side or right side arbitrarily.
Please tell whether the balance can measure an object of weight M.
 

Input
The first line is a integer  T(1T5) , means T test cases.
For each test case :
The first line is  N , means the number of weights.
The second line are  N  number, i'th number  wi(1wi100)  means the i'th weight's weight is  wi .
The third line is a number  M M  is the weight of the object being measured.
 

Output
You should output the "YES"or"NO".
 

Sample Input
   
   
   
   
1 2 1 4 3 2 4 5
 

Sample Output
   
   
   
   
NO YES YES
Hint
For the Case 1:Put the 4 weight alone For the Case 2:Put the 4 weight and 1 weight on both side


题目大意:有n个砝码和一个没有刻度的天平,砝码可以放在任意一侧,问最后能否称出k的物品


先考虑只在只有砝码的一侧放置,有两种状态,当前砝码放或不放,可以用dp解决

当i可以称出t时,i+w也可以称出

把所有物体一侧的砝码可以等效成负的砝码加在只有砝码的一侧,这样就把物体和砝码分开了

因此可能存在“负”的质量,所以可以全部加上一个常数,防止越界

由于当前砝码的更新会影响后续的更新,所以需要用二维数组表示

#include <cstdio>
#include <cstring>

using namespace std;

int T,n,m,w,k,i,j,sum,mn,x;
bool dp[2][4105];
const int ORD=2055;

int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        sum=0;
        mn=105;
        memset(dp,false,sizeof(dp));
        dp[0][ORD]=true;
        for(i=0;i<n;++i) {
            scanf("%d",&w);
            sum+=w;
            for(j=0;j<4005;++j)
                if(dp[i&1][j])//给所有砝码一侧的重量加上一个常数,不必再考虑越界问题
                    dp[(i+1)&1][j]=dp[(i+1)&1][j+w]=dp[(i+1)&1][j-w]=true;
        }
        scanf("%d",&m);
        while(m--) {
            scanf("%d",&k);
            printf("%s\n",0<=k&&k<=sum&&dp[n&1][k+ORD]?"YES":"NO");
        }
    }
    return 0;
}

———————————————————万年2题的旅游分割线———————————————————

HDU-5617 Jam's maze

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

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)


Problem Description
Jam got into a maze, he has to find a palindrome path from  (1,1)  to  (N,N)  to get out.
However he is not only thinking about how to get out of the maze,
but also counting the number of ways he can get out.

The maze a  NN  grid. On each cell is a uppercase letter.
Jam is at upper-left corner  (1,1)  now, and the exit is at lower-right corner  (N,N) .
Jam can only go down or go right.
Considering the number of palindrome path may be huge, you just need to output the number mod  5201314 .
 

Input
The first line is  T(1T10)  means  T  Case.
For each case:
The first line is  N(1N500)  means the size of the maze.
Then  N  lines follow, each line has  N  uppercase letter.
 

Output
For each testcase, output the number of palindrome path mod  5201314 .
 

Sample Input
   
   
   
   
1 4 ABCD BEFE CDEB GCBA
 

Sample Output
   
   
   
   
12
Hint
there are 1 solutions is"ABCDCBA" there are 1 solutions is"ABCGCBA" there are 4 solutions is"ABEDEBA" there are 6 solutions is"ABEFEBA"

题目大意:有一个n*n的迷宫,每个点有一个大写字母,从左上角走到右下角,每次只能往下或往右走,求有多少种路径所得字符串是回文的


结果很大,应该往dp想

由于起点和终点确定,所以可以同时从起点和终点走,设状态为dp[x1][y1][x2][y2],初始若mp[1][1]==mp[n][n],则dp[1][1][n][n]为1,否则直接输出0

枚举合法的位置,若mp[x1][y1]==mp[x2][y2],则进行状态转移

dp[x1][y1][x2][y2]可由dp[x1-1][y1][x2+1][y2],dp[x1-1][y1][x2][y2+1],dp[x1][y1-1][x2+1][y2],dp[x1][y1-1][x2][y2+1]转移而来

由于这样会MLE,所一可以用dp[step][x1][x2]表示状态,step表示目前是第step步,则可求出y1和y2,仍会MLE;又当前步状态只与上一步状态有关,所以可以用滚动数组

#include <cstdio>
#include <cstring>

using namespace std;

int T,n,x1,x2,y1,y2,step,cur,ans;
int dp[2][505][505];
char mp[505][505];

int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        for(x1=1;x1<=n;++x1)
            scanf("%s",mp[x1]+1);
        if(mp[1][1]!=mp[n][n]) {
            printf("0\n");
            continue;
        }
        memset(dp,0,sizeof(dp));
        dp[0][1][n]=1;
        cur=ans=0;
        for(step=1;step<n;++step) {
            cur^=1;
            memset(dp[cur],0,sizeof(dp[cur]));
            for(x1=1;x1<=n&&x1<=step+1;++x1) {
                y1=step-x1+2;
                for(x2=n;x2>0&&x2>=n-step;--x2) {
                    y2=2*n-x2-step;
                    if(mp[x1][y1]==mp[x2][y2])
                        dp[cur][x1][x2]=(dp[cur^1][x1][x2]+dp[cur^1][x1-1][x2]+dp[cur^1][x1][x2+1]+dp[cur^1][x1-1][x2+1])%5201314;
                }
            }
        }
        for(x1=1;x1<=n;++x1)
            ans=(ans+dp[cur][x1][x1])%5201314;
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(dp,HDU,BestCoder)