Codeforces Round #613 (Div. 2)

B

题目大意

给定一个数列,问整个区间和以及部分区间和哪个大。

整个区间和小于部分和就说明,肯定另一部分区间加起来和小于0,给贡献拉后腿,所以我们可以从判断从左边开始累加还有右边开始累加的和有小于0的直接就是整体输给部分

 #include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
typedef long long ll;
int n,m,a[maxn],T;
char ch[maxn];
vector<int>v;
ll l,r,maxx,sum,res,vis;
int minn;
int main()
{
    scanf("%d",&T);
    while(T--){
    vis=sum=res=0;
    maxx=-0x3f3f3f3f;
    minn=0x3f3f3f3f;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        sum+=a[i];
    }
    for(int i=1;i<=n;i++){
        sum-=a[i];
        res+=a[i];
        if(sum<=0&&i!=n) {vis=1;break;}
        if(res<=0){vis=1;break;}
    }
//    printf("^%lld %lld
",sum,maxx);
    if(vis==0) puts("YES");
    else puts("NO");
 
    }
}

  

C. Fadi and LCM (CF 1285 C)

题目大意

给定xx,找出一对a,ba,b使得lcm(a,b)=xmax(a,b)最小。

lcm(a,b)=a*b/gcd(a,b)=x;

可以直接令gcd(a,b)=1,然后从小枚举a,算出b,这样的话b就是从大到小,a从小到大不断向中间靠拢,可得出最优解

#include<bits/stdc++.h>
using namespace std;
const long long  maxn=LLONG_MAX;
typedef long long ll;
int n,m,T;
 
vector<int>v;
ll l,r,maxx,sum,res,vis;
int minn;
ll gcd(ll m, ll n) {
	return m % n == 0 ? n : gcd(n, m % n);
}
int main() {
	ll x;
	while (~scanf("%lld",&x)) {
			pair<ll, ll > pr;
			ll i, m;
			m = sqrt(x);
			ll a, b;
			pr.first = pr.second =maxn;
			for (i=1;i<=m;i++) {
				a=i;
				if (x%a==0) {
					b=x/a;
					ll g=gcd(a, b);
					if (b<pr.second&&(g==1||a==1)) {
						pr.first=a;
						pr.second=b;
					}
				}
			}
			cout << pr.first << ' ' << pr.second << endl;
	}
	return 0;
}

D  Dr. Evil Underscores

题目大意:给一组数,找一个x使的x和所有给的数的异或值的最大值max最小,求这个max

解题思路:从每个数的二进制第30位开始到第1位,如果这一位对于所有的数来说都是0或者都是1,那么max在这一位就可以取0(因为要你的max最小,那你x可以去和这个位置一样的0/1,max这个位置肯定就是一个0,),如果这一位既有0又有1,那么这一位一定是1,无论你x取1/0,都得和其中一个异或出一个1出来,因为他是最大值max。对于这种情况,x的取值就有两种,对于x取1和x取0,那我们问题就是我们x取1还是0来让这个max最小,所以我们要递归下去来取最小,我们用vect容器v1表示存起来这个位置是1的数字,v0表示这个位置是0的数字。然后开始下面进行判断,如果v1里面没有数字,说明都在v0里,也就是该位置全是0,那么max这位置是0,直接递归下去判断下一个位置,v0也是如此。但是当出现v1,v0都非空,那我们可以进行我们就要兵分两路了,因为对于对应的x不一样了,min(dfs(v1),dfs(v0)

表示后面的值得取小,所以可以调用自己。

v1的x对应0,v0的x对应1,然后取最小值,。因为该位置必取1,所以还得加上1<<bit;

#include <iostream>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <stack>
#define FT(a, b) memset(a, b, sizeof(a))
#define FAT(a) memset(a, 0, sizeof(a))
using namespace std;
typedef long long ll;
const int M = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
vector<ll> v;
ll dfs(vector<ll> &v, int bit)
{
    vector<ll> v0, v1;
    if (bit < 0 || v.size() == 0)
        return 0;
    for (ll &j : v)
    {
        if ((j >> bit) & 1)
            v1.push_back(j);
        else
            v0.push_back(j);
    }
    if (v1.size() == 0)
        return dfs(v0, bit - 1);
    if (v0.size() == 0)
        return dfs(v1, bit - 1);
    return min(dfs(v0, bit - 1), dfs(v1, bit - 1)) + (1<<bit);
}
int main()
{
 
    int n;
    v.clear();
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        ll x;
        scanf("%lld", &x);
        v.push_back(x);
    }
    ll ans = dfs(v, 30);
 
    printf("%lld
", ans);
    return 0;
}

  

原文地址:https://www.cnblogs.com/hgangang/p/12186701.html