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; }