bestcoder题解

来源:互联网 发布:传奇3地图编辑器源码 编辑:程序博客网 时间:2024/06/05 20:42

Jam's math problem

题意:给出二元一次函数式的a,b,c问该式子能否被因式分解,十字交叉法,直接暴力

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;#define LL __int64int main(){    int t;    scanf("%d",&t);    while(t--)    {        LL a,b,c;        scanf("%I64d %I64d%I64d",&a,&b,&c);        bool sign=false;        if((b*b-4*a*c)<0)            printf("NO\n");        else        {            for(int i=1;i<=sqrt(a);i++)            {                for(int j=1;j<=sqrt(c);j++)                {                    if((a%i==0)&&(c%j==0))                    {                        LL k,q,m,p;                        p=i,q=a/i,k=j,m=c/j;                        if((q*k+m*p==b)||(m*q+p*k==b))                        {                            sign=true;                            break;                        }                     }                 }                if(sign==true)                    break;            }        if(sign==true)            printf("YES\n");        else            printf("NO\n");        }    }    return 0;}

Jam's balance

解题思路:01背包的思想。如果全部砝码放在右边那么最重可以有2000个重量,左右都可以放,将2000作为平衡点,DP方程如下:

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;const int maxn=25;const int maxm=4000+5;int dp[maxn][maxm];//maxn代表砝码的总数量,以2000为平衡点int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n;        scanf("%d",&n);        int sum=0;        int weight[25];        for(int i=1;i<=n;i++)        {            scanf("%d",&weight[i]);            sum+=weight[i];        }        memset(dp,0,sizeof(dp));        dp[0][2000]=1;//以2000为平衡点,设dp[i][j]表示用了i个砝码称j重量是否可行        for(int i=1;i<=n;i++)        {            for(int j=4000;j>=0;j--)            {                if(dp[i-1][j])                //转移一,如果只用了i-1个砝码就称出了j,那么多加一个砝码也足够称出j                     dp[i][j]=1;                if(j+weight[i]<=4000 && dp[i-1][j])                    dp[i][j+weight[i]]=1;    //转移二,如果用i-1个砝码称出了j,那么我在右边多加一个砝码,就可以称出j+w[i]                 if(j-weight[i]>=2000 && dp[i-1][j])                    dp[i][j-weight[i]]=1;    //转移三,如果用i-1个砝码称出了j,那么我在左边多加一个砝码,就可以称出j-w[i]              }        }        int Case;        scanf("%d",&Case);        while(Case--)        {            int x;            scanf("%d",&x);            if(!dp[n][x + 2000] || x>sum)                printf("NO\n");            else                printf("YES\n");        }    }    return 0;}


0 0