BestCoder Round #70 总结

116 篇文章 0 订阅
16 篇文章 0 订阅

Jam's math problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 173    Accepted Submission(s): 88


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^2+6*x+5$ into $(x+1)(x+5)$
 

Source
 
题意:
Jam有道数学题想向你请教一下,他刚刚学会因式分解比如说,x^2+6x+5=(x+1)(x+5)x2+6x+5=(x+1)(x+5)
就好像形如 ax^2+bx+cax2+bx+c => pqx^2+(qk+mp)x+km=(px+k)(qx+m)pqx2+(qk+mp)x+km=(px+k)(qx+m)
但是他很蠢,他只会做p,q,m,kp,q,m,k为正整数的题目
请你帮助他,问可不可以分解
官方题解:第一道题比较简单,可以说是简单的模拟题,我们考虑到a,b,ca,b,c都是10^{9}109的,所以我们决定要把时间复杂度降下来,对于每一个数,因为考虑到都是正数,所以我们处理起来就方便很多,打个比方32=2*1632=216,那么枚举到22的时候就可以得出1616,这样子的话时间就变为O(\sqrt{a}\sqrt{b})O(ab),轻松解决这道题
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        int ok=0;
        for(int i=1;i<=a/2+1;i++)
        {
            if(a%i==0)
            {
                for(int j=1;j<=c/2+1;j++)
                {
                    if(c%j==0)
                    {
                        int x=a/i;
                        int y=c/j;
                        if(x*j+y*i==b)
                        {
                            ok=1;
                            break;
                        }
                    }
                }
            }
            if(ok)
                break;
        }
        if(ok)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

Jam's balance

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 154    Accepted Submission(s): 67


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
题意:
Jam有NN个砝码和一个没有游标的天平,现在给他(1 \leq N \leq 20)(1N20)个砝码,砝码可以放左边,也可以放右边,问可不可以测出所问的重量, 问的个数为(1 \leq M \leq 100)(1M100)个.
官方题解:这道题可以放左边,可以放右边,N=20N=20显然每种状态都枚举是不太现实的,因为每组砝码都可以变成很多种重量,当然也不排除有人乱搞过了这一题,其实这道题是一道贪心的思想,我们看到ww不大,所以可以用0101背包扫一次,当然这还是不够的,这只能放一边,考虑到可以放另一边,就是可以有减的关系,所以反着再背包一遍,注意要判断边界。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxm=2e3+10;
int dp[maxm];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        int n,a;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a);
            for(int j=0;j<=2000;j++)
            {
                if(dp[j]&&j>a)
                {
                    dp[j-a]=1;
                }
            }
            for(int j=2000;j>=0;j--)
            {
                if(dp[j]==1)
                {
                    dp[j+a]=1;
                }
            }
        }
        int q;
        scanf("%d",&q);
        for(int i=0;i<q;i++)
        {
            int x;
            scanf("%d",&x);
            if(x<0||x>2000||!dp[x])
                printf("NO\n");
            else
                printf("YES\n");
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值