Codeforces Round #652 (Div. 2)

A - FashionabLee

题意

问你一个正n边形,您能否旋转它,让他的某一条边平行于x轴另一条边平行于y轴。

思路

要让他有平行于x轴的边的同时,也有平行于y轴的边。

那么我们只需要让他n边形的360/n是90度的倍数关系即可。画图验证更快。

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define debug(case,x); cout<<case<<"  : "<<x<<endl;
#define open freopen("ii.txt","r",stdin)
#define close freopen("oo.txt","w",stdout)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
using namespace std;
//#define int long long
#define lson rt<<1
#define rson rt<<1|1
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<long long,long long> PII;
const int maxn = 1e6 + 10;
 
 
 
 
void solve(){
    ll n;cin>>n;
    if (n % 4 == 0) cout << "YES\n";
    else
        cout << "NO\n";
}
 
 
int main(){
    int t;cin>>t;
    while(t--){
        solve();
    }
 
    return 0;
}

B - AccurateLee

题意

给你一个01串,如果两个字符左边的=1,右边的=0。那么我们可以选择一个消除,让你找到消除到不能消除为止,如果消除后长度相同,那么输出字典序小的。

思路

我们只需要判断在左边的0和右边的1这样的01是消除不了的。在中间的01串只要有1在0的左边,也就是0的数量和1的数量均不为0。这样问题就得到了解决。

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define debug(case,x); cout<<case<<"  : "<<x<<endl;
#define open freopen("ii.txt","r",stdin)
#define close freopen("oo.txt","w",stdout)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
using namespace std;
//#define int long long
#define lson rt<<1
#define rson rt<<1|1
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<long long,long long> PII;
const int maxn = 1e6 + 10;

char str[maxn];
void solve(){
    int len;
    scanf("%d", &len);
    getchar();
    scanf("%s", str);
    int cnt1 = 0, cnt2 = 0;
    int i = 0;
    while (str[i] == '0' && i < len) ++i;
    int j = len - 1;
    while (str[j] == '1' && j >= 0) --j;
    for (int k = i; k <= j; ++k) {
        if (str[k] == '0') ++cnt1;
        else
            ++cnt2;
    }
    int ans = cnt1 + cnt2;
    for (int k = 0; k < i; ++k) cout << 0;
    if (cnt1!=0&&cnt2!=0) cout << 0;
    for (int k = j + 1; k < len; ++k) cout << 1;
    cout << endl;
}


int main(){
    int t;
    scanf("%d", &t);
    // cin>>t;
    while(t--){
        solve();
    }

    return 0;
}

C - RationalLee

题意

给你一些n个价值,有k个朋友。然后n个价值分别为\(a_1,a_2,…a_n\),然后输入k个数,代表的是分配给朋友的价值的个数。让你求所有分给朋友的数的\(max(\sum (min_k+max_k))\)

思路

首先我们知道的是如果给第k个朋友只能分1个价值,那么这个朋友的\(max+min\)就是\(x*2\)

然后我们去考虑整体。为了让所求和最大,显然我们要让小的价值出现的尽量的少,那么我们就先选每个朋友除了最大的价值的剩下能选择的个数(\(w_k-1\))。在选择这些的时候我们从左边开始双指针,跳范围,这样每选一个小的数就跳过去(\(w_k-1)\)个,然后继续选以此类推。

选择打的数的时候我们从右边开始选择,然后选择的时候也是有条件的,我们先给w小的选。

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define debug(case,x); cout<<case<<"  : "<<x<<endl;
#define open freopen("ii.txt","r",stdin)
#define close freopen("oo.txt","w",stdout)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
using namespace std;
//#define int long long
#define lson rt<<1
#define rson rt<<1|1
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<long long,long long> PII;
const int maxn = 1e6 + 10;

int a[maxn], w[maxn];
void solve(){
    int n, k;
    cin >> n >> k;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    for (int i = 1; i <= k; ++i) cin >> w[i];
    sort(a + 1, a + 1 + n);
    ll ans = 0;
    sort(w + 1, w + 1 + k, greater<int>());
    int l = 1, r = n;
    for (int i = 1; i <= k;++i){
        if (w[i] == 1) break;
        ans += a[l];
        l += (w[i]-1);
    }
    for (int i = k; i >= 1;--i){
        if(w[i]==1){
            ans += 2 * a[r];
        }else
            ans += a[r];
        --r;
    }
    cout << ans << endl;
}


int main(){
    int t;
    // scanf("%d", &t);
    cin>>t;
    while(t--){
        solve();
    }

    return 0;
}

D - TediousLee

题意

我解释不了。

思路

递推,找规律。

像如这样的题我们是先考虑找规律来试试的,因为毫无头绪。

然后我们在纸上仔细的画图演算选择。

\[dp[i]=2*dp[i-2]+dp[i-1]+(i\%3==0) \]

每过两次第三次就可以选择一次根节点的clwa。

好一点的讲解

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define debug(case,x); cout<<case<<"  : "<<x<<endl;
#define open freopen("ii.txt","r",stdin)
#define close freopen("oo.txt","w",stdout)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
using namespace std;
//#define int long long
#define lson rt<<1
#define rson rt<<1|1
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<long long,long long> PII;
const int maxn = 2e6 + 10;
const int mod = 1e9 + 7;
int dp[maxn];
bool vis[maxn];
int main(){
    vis[1] = vis[2] = 0;
    dp[1] = dp[2] = 0;
    for (int i = 3; i < maxn;++i){
        dp[i] = (2ll * dp[i - 2] + dp[i - 1]) % mod;
        if (!vis[i - 2] && !vis[i - 1]) dp[i] += 1, vis[i] = 1;
        else
            vis[i] = 0;
    }
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        cout << (4ll * dp[n] % mod) << endl;
    }

    return 0;
}

E - DeadLee

题意

题给出n个不同类型的食物,m个朋友。让你给朋友定一个来的顺序,以满足以下条件:

  • 来的每个人都会吃掉自己喜欢的食物(只要存在)x和y
  • 如果仅剩一个x或y那么也可以,但是如果同时存在必须同时吃

思路

动态贪心。

我们从后往前选,如果\(num[x]/num[y]\leq w[i]\),那么我就把吃这种食物的安排到最后面。

因为他吃的这种食物一定存在。那么我们让他最后吃,然后将另一种食物省下来给其他人吃。

好一点的讲解

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define debug(case,x); cout<<case<<"  : "<<x<<endl;
#define open freopen("ii.txt","r",stdin)
#define close freopen("oo.txt","w",stdout)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
using namespace std;
//#define int long long
#define lson rt<<1
#define rson rt<<1|1
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<long long,long long> PII;
const int maxn = 1e6 + 10;

int w[maxn],num[maxn];
bool vis[maxn];
pair<int, int> a[maxn];
void solve(){
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) cin >> w[i];
    vector<vector<int> > edge(n + 10);
    for (int i = 1; i <= m;++i){
        int x, y;
        cin >> x >> y;
        ++num[x];
        ++num[y];
        a[i] = {x, y};
        edge[x].push_back(i);
        edge[y].push_back(i);
    }
    vector<int> ans;
    queue<int> q;
    for (int i = 1; i <= n;++i)
        if (num[i] <= w[i]) q.push(i);
    
    while(!q.empty()){
        int now = q.front();
        q.pop();
        for(auto x:edge[now]){
            if (vis[x]) continue;
            vis[x] = 1;
            ans.push_back(x);
            int v = a[x].first;
            if (v == now) v = a[x].second;
            if (--num[v] == w[v]) q.push(v);
        }
    }
    if(ans.size()==m){
        cout << "ALIVE\n";
        reverse(ans.begin(), ans.end());
        for (auto x : ans) cout << x << " ";
    }else
        cout << "DEAD\n";
}


int main(){
    int t;
    // scanf("%d", &t);
    // cin>>t;
    // while(t--){
    //     solve();
    // }
    solve();

    return 0;
}
posted @ 2020-07-30 00:34  waryan  阅读(108)  评论(0)    收藏  举报