Codeforces Round # 636 (Div. 3) Supplement


A. Candies and other
ratio sequences are summed to get the expressions of k and x. Just enumerate k, because it is a power function, k is not very large

Code

#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
inline void read(int &p)
{
    p=0;int flag=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
    while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
	#ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    int q;
    read(q);
    while(q--){
        int n;
        cin>>n;
        ll k,ans;
        for(k=2;;k++){
            ll cnt=(1<<k)-1;
            if(n%cnt==0){
                ans=n/cnt;break;
            }
        }
        cout<<ans<<endl;
    }
 	return 0;
}
 

B. Balanced Array
can be divided as long as n is 4.
My structure is that even part outputs 2i, odd part outputs 2i-1 in the first half, and 2i + 1 in the latter half.

Code

#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
inline void read(int &p)
{
    p=0;int flag=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
    while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
	#ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    int q;
    cin>>q;
    while(q--){
        int n;
		cin>>n;
		n/=2;
		if(n%2){
			printf("NO\n");
			
		}
		else{
			printf("YES\n");
			for(int i=1;i<=n;i++) cout<<2*i<<" ";
			for(int i=1;i<=n;i++){
				if(i<=n/2) cout<<2*i-1<<" ";
				else cout<<2*i+1<<" ";
			}
			cout<<"\n";
		}
    }
 	return 0;
}
 

C. Alternating Subsequence
is equivalent to that the given sequence is a sequence of negative numbers and positive numbers. To select a number from each negative part and each positive part, construct a new series, and let the sum of this series be the largest. . In this way, you only need to choose the largest number in each part.

Code

#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
inline void read(int &p)
{
    p=0;int flag=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
    while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
	#ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    int q;
    cin>>q;
    while(q--){
        int n;
		cin>>n;
		vector<int> a(n+1);
		for(int i=1;i<=n;i++) {cin>>a[i];}
		ll ans=0;
		ll pre=a[1],now=1234567890;
		for(int i=1;i<=n;i++){
			now=a[i];
			if(pre>0&&now>0){
				now=max(pre,now);
				pre=now;
			}
			else if(pre<0&&now<0){
				now=max(pre,now);
				pre=now;
			}
			else{
				ans+=pre;
				pre=now;
			}
		}
		ans+=pre;
		cout<<ans<<endl;
    }
 	return 0;
}
 

D. Constant Palindrome Sum
For each log, and their sum, we can use the cnt array to store the number of occurrences of sum, and we can also know that the log only changes the range of sums that can be obtained by one element, and use a difference array Pref is used to store the upper and lower bounds of this range. After counting all the numbers, the difference array sums the prefixes to know how many groups of numbers can be operated for no more than 1 time for a certain x. To enumerate all possible x, the corresponding answer is to obtain the logarithm of x less than once and subtract the logarithm of x, plus 2 times the operation twice to get the logarithm of x. The total log minus the logarithm of x not more than 1 operation is the logarithm of x after two operations.

Code

#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
inline void read(int &p)
{
    p=0;int flag=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
    while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
vector<int> a;
map<int,int> cnt,pref;
int main()
{
	#ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    int q;
    read(q);
    while(q--){
        int n,k;
        cin>>n>>k;
        a.resize(n);
        cnt.clear(),pref.clear();
        for(auto &x:a) read(x);
        for(int i=0;i<n/2;i++) cnt[a[i]+a[n-i-1]]++;
        for(int i=0;i<n/2;i++){
            int l=a[i],r=a[n-i-1];
            pref[max(l,r)+k+1]--;
            pref[min(l,r)+1]++;
        }
        for(int i=2;i<=2*k;i++){
            pref[i]+=pref[i-1];
        }
        int ans=99999999;
        for(int i=2;i<=2*k;i++){
            ans=min(ans,pref[i]-cnt[i]+2*(n/2-pref[i]));
        }
        cout<<ans<<"\n";
    }
 	return 0;
}
 

E. Weights Distributing
first use bfs to preprocess the shortest path with abc as the starting point (the length of each road is regarded as 1, the number of roads to be taken), and sort the cost of the road from small to large. Find an intermediary point x so that the way to go becomes a——x——b——x——c. This x can also be b. Count the number of the least way to go for each x. If a to x takes m roads, x to b takes n roads, x to c takes q roads, then you can make n correspond to the first n small costs (because you have to walk twice), and the remaining m + p roads correspond to the previous n + 1 to m + p small cost, you can get the corresponding minimum cost. It is sufficient to traverse x to update the minimum value.

Code

#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
inline void read(int &p)
{
    p=0;int flag=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
    while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
vector<vector<int> > mp;
void bfs(int a,vector<int> & d){
    queue<int> q;
    q.push(a);
    d[a]=0;
    while(!q.empty()){
        int x=q.front();
        q.pop();
        for(auto i:mp[x]){
            if(d[i]!=INF) continue;
            d[i]=d[x]+1;
            q.push(i);
        }
    }
}
int main()
{
	#ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    int q;
    read(q);
    while(q--){
        int n,m,a,b,c;
        cin>>n>>m>>a>>b>>c;
        vector<int> p(m);
        for(auto &x:p) read(x);
        sort(p.begin(),p.end());
        mp=vector<vector<int> >(n);
        for(int i=0;i<m;i++){
            int x,y;
            read(x),read(y);
            x--;y--;
            mp[x].push_back(y);
            mp[y].push_back(x);
        }
        a--;b--;c--;
        vector<int> aa(n,INF),bb(n,INF),cc(n,INF);
        bfs(a,aa);
        bfs(b,bb);
        bfs(c,cc);
        vector<ll> d(m+1);
        for(int i=1;i<=m;i++) d[i]=d[i-1]+p[i-1];
        ll ans=1e18;
        for(int i=0;i<n;i++){
            if(aa[i]+bb[i]+cc[i]>m) continue;
            ans=min(ans,d[aa[i]+bb[i]+cc[i]]+d[bb[i]]);
        }
        cout<<ans<<"\n";
    }
 	return 0;
}
 

F. Restore the Permutation by Sorted Segments The
input gives all 2 to n elements of variable length r. Enumerate the first number in the array, suppose it is fst, and delete fst in all fragments that contain fst, then there will be one element left in the fragment with the second element as r, namely a [2], then put Delete a [2] in all the fragments containing a [2], you can get a [3], and you can get all the elements by repeating this operation. After finding an array that may match, check whether the n-1 fragments given by the input are satisfied. These fragments are more convenient to maintain with set.

Code

#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
inline void read(int &p)
{
    p=0;int flag=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
    while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
	#ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    int q;
    read(q);
    while(q--){
        int n;
        read(n);
        vector<set<int> > segs;
        for(int i=0;i<n-1;i++){
            int k;
            read(k);
            set<int> seg;
            for(int i=0;i<k;i++){
                int x;
                read(x);
                seg.insert(x);
            }
            segs.push_back(seg);
        }
        for(int fst=1;fst<=n;fst++){
            bool flag=true;
            vector<int> ans;
            vector<set<int> > cur=segs;
            for(auto & x:cur){
                if(x.count(fst)){
                    x.erase(fst);
                }
            }
            ans.push_back(fst);
            for(int i=1;i<n;i++){
                int num=0;
                int nxt=-1;
                for(auto &x:cur){
                    if(x.size()==1){
                        ++num;
                        nxt=*x.begin();
                    }
                }
                if(num!=1){
                    flag=false;
                    break;
                }
                for(auto & x:cur){
                    if(x.count(nxt)){
                        x.erase(nxt);
                    } 
                }
                ans.push_back(nxt);
            }
            //check
            if(flag){
                set<set<int> > all(segs.begin(),segs.end());
                for(int i=1;i<n;i++){
                    set<int> seg;
                    seg.insert(ans[i]);
                    bool ok=false;
                    for(int j=i-1;j>=0;j--){
                        seg.insert(ans[j]);
                        if(all.count(seg)){
                            ok=true;
                            break;
                        }
                    }
                    if(!ok){
                        flag=false;
                        break;
                    }
                }
            }
            if(flag){
                for(auto x:ans){
                    cout<<x<<" ";
                }putchar('\n');
                break;
            }
        }
    }
 	return 0;
}
 
 

Guess you like

Origin www.cnblogs.com/DinoMax/p/12757996.html