BestCoder Round #78 (div.2) A B




链接:戳这里


CA Loves Stick
 Time Limit: 2000/1000 MS (Java/Others)   Memory Limit: 262144/262144 K (Java/Others)
问题描述
CA喜欢玩木棍。
有一天他获得了四根木棍,他想知道用这些木棍能不能拼成一个四边形。(四边形定义:https://en.wikipedia.org/wiki/Quadrilateral)
输入描述
第一行 T,表示有 T 组数据。
接下来 T 组数据,每组数据包含四个整数 a,b,c,d,分别为四根木棍的长度。
1≤T≤1000, 0≤a,b,c,d≤2^​63−1
输出描述
对于每个数据,如果能拼成一个四边形,输出“Yes”;否则输出“No”(不包括双引号)。
输入样例
2
1 1 1 1
1 1 9 2
输出样例
Yes
No


思路:额,对于出题人也是醉了,居然卡long long溢出,所以还是改成减法吧

四边形定义:任意一边小于三边和  对了还有=0的情况  真的是!!!无力吐槽


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
int T;
ll a[10];
int main(){
    scanf("%d",&T);
    while(T--){
        for(int i=0;i<4;i++) scanf("%I64d",&a[i]);
        if(a[0]==0 || a[1]==0 || a[2]==0 || a[3]==0) {
            cout<<"No"<<endl;
            continue;
        }
        sort(a,a+4);
        if(a[0]>a[3]-a[2]-a[1])
            cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}



CA Loves GCD
 Time Limit: 6000/3000 MS (Java/Others)   Memory Limit: 262144/262144 K (Java/Others)
问题描述
CA喜欢是一个热爱党和人民的优秀同♂志,所以他也非常喜欢GCD(请在输入法中输入GCD得到CA喜欢GCD的原因)。
现在他有N个不同的数,每次他会从中选出若干个(至少一个数),求出所有数的GCD然后放回去。
为了使自己不会无聊,CA会把每种不同的选法都选一遍,CA想知道他得到的所有GCD的和是多少。
我们认为两种选法不同,当且仅当有一个数在其中一种选法中被选中了,而在另外一种选法中没有被选中。
输入描述
第一行 T,表示有 T 组数据。
接下来 T 组数据,每组数据第一行一个整数 N,表示CA的数的个数,接下来一行 N 个整数A​i
​​  表示CA的每个数。1≤T≤50, 1≤N≤1000, 1≤A​i≤1000
输出描述
对于每组数据输出一行一个整数表示CA所有的选法的GCD的和对100000007 取模的结果。
输入样例
2
2
2 4
3
1 2 3
输出样例
8
10


思路:这道题最后也没做出来,太弱了,想的时候肯定知道是dp,想过dp[i][j]是当前i各数最小公倍数为j的种数,但是处理的时候想着容斥去了,判断当前的j不是最小公倍数的时候多算了多少,想复杂了  啊啊啊啊  居然没有想到枚举到当前第i数,选或不选  最小公倍数为j的个数,  可以把当前a[i]加到gcd(j,a[i])中去   哎 还是太弱了   转个弯就想到了

dp[i][j]+=dp[i-1][j]  (不选)

dp[i][gcd(j,a[i])]+=dp[i-1][j] (选了之后会有什么影响)


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
#define mod 100000007
using namespace std;
int a[100100];
int T,n;
ll dp[1010][1010],g[1010][1010];  /// 当前选第i个数 且已选的数的gcd=j  个种数
int gcd(int x,int y){
    return x%y==0 ? y:gcd(y,x%y);
}
int main(){
    scanf("%d",&T);
    for(int i=1;i<=1000;i++){
        for(int j=1;j<=1000;j++){
            g[i][j]=gcd(i,j);
        }
    }
    while(T--){
        mst(dp,0);
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        for(int i=1;i<=n;i++) dp[i][a[i]]=1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=a[i];j++){
                dp[i][j]=(dp[i][j]+dp[i-1][j])%mod;
                int k=g[j][a[i]];
                dp[i][k]=(dp[i][k]+dp[i-1][j])%mod;
            }
        }
        ll ans=0;
        for(int i=1;i<=a[n];i++){
            ans+=(ll)dp[n][i]*i;
            ans%=mod;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(BestCoder Round #78 (div.2) A B)