bestcoder题解

Jam's math problem

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

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define LL __int64
int 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值