Codeforces Round #647 (Div. 2) 1364 ABCD題解

首先

Cue一下隊友鏈接:

核心選手:https://me.csdn.net/qq_43559193

核心選手:https://me.csdn.net/weixin_43916298

比賽鏈接:https://codeforces.ml/contest/1362

目錄

A. Johnny and Ancient Computer

題目思路:

題目思路

Code:

 B. Johnny and His Hobbies

題目大意:

題目思路:

Code:

C. Johnny and Another Rating Drop

題目大意:

題目思路:

Code:

D. Johnny and Contribution

題目思路:

題目思路:

Code:

 


 

A. Johnny and Ancient Computer

題目思路:

給出n、m,每次操作可以*2 *4 *8 /2 /4 /8,問最少幾步n可以變爲m。

題目思路

把除法歸結於乘法、讓n成爲min(n,m)中小的

使得n 變爲 m。

所以令  temp = m/n 

這樣如果temp是奇數、那麼一定不行

否則的話 看一下是否可以被2 4 8 整除,貪心先除大的

Code:

/*** keep hungry and calm CoolGuang!***/
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll INF=1e18;
const int maxn=1e6+6;
const int mod=1e9+7;
const double eps=1e-15;
inline bool read(ll &num)
{char in;bool IsN=false;
    in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,p;
ll a[3]={8,4,2};
int main(){
    int T;scanf("%d",&T);
    while(T--){
        read(n);read(m);
        if(n==m) {
            printf("0\n");
            continue;
        }
        if(n<m) swap(n,m);
        if(n%m != 0) printf("-1\n");
        else{
            ll temp = n/m;
            ll ans = 0;
            if(temp&1) printf("-1\n");
            else{
                for(int i=0;i<3;i++){
                    while(temp%a[i]==0){
                        temp/=a[i];
                        ans++;
                    }
                }
                if(temp==1)  printf("%lld\n",ans);
                else printf("-1\n");
            }
        }
    }
    return 0;
}
/**
1 1 1 1
**/

 B. Johnny and His Hobbies

題目大意:

找出一個最小的k,使得數組A的每個數異或k之後,數組A不變

題目思路:

暴力(服了,我寫半小時,我以爲要On)..

枚舉1~1023 看哪個可以就好了

Code:

/*** keep hungry and calm CoolGuang!***/
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll INF=1e18;
const int maxn=1e6+6;
const int mod=1e9+7;
const double eps=1e-15;
inline bool read(ll &num)
{char in;bool IsN=false;
    in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,p;
ll num[maxn];
ll c[maxn];
map<ll,ll>mp,pre;
void push(){
    ll temp = 0;
    for(int k=1;k<=1024;k++){
        mp.clear();
        for(int i=1;i<=n;i++){
            mp[num[i]^k] ++;
        }
        int f = 0;
        for(auto x:mp){
            if(pre[x.first] != x.second) f=1;
        }
        if(!f){
            printf("%d\n",k);
            return ;
        }

    }
    printf("-1\n");
}
int main(){
    int T;scanf("%d",&T);
    while(T--){
        read(n);
        mp.clear();
        pre.clear();
        for(int i=1;i<=n;i++){
            read(num[i]);
            pre[num[i]] = 1;
        }
        push();
    }
    return 0;
}
/**
1 1 1 1
**/

C. Johnny and Another Rating Drop

題目大意:

 輸入n,輸出1~n,2進制下相鄰不同的位數差之和

題目思路:

一眼打表題、並且絕對是線性的(沒有取餘 且 n太大)

    for(int i=1;i<=100;i++){
        ll temp = 0;
        for(int k=1;k<=i;k++){
            for(int j=0;j<10;j++){
                int x = k>>j&1,y = (k-1)>>j&1;
                if(x^y) temp++;
            }
        }
        printf("%d %lld\n",i,temp);
    }

 

看一下5和2,與4和2,這個題基本就完事了

f(x) = f(floor(x/2)) + x 

之後寫一個log的遞歸

Code:

/*** keep hungry and calm CoolGuang!***/
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll INF=1e18;
const int maxn=1e6+6;
const int mod=1e9+7;
const double eps=1e-15;
inline bool read(ll &num)
{char in;bool IsN=false;
    in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,p;
ll solve(ll x){
    if(x==1) return 1;
    return solve(x/2)+x;
}
int main(){
    int T;scanf("%d",&T);
    while(T--){
        read(n);
        printf("%lld\n",solve(n));
    }
    return 0;
}
/**
5 6|9|13 14|17|20 21|
**/

D. Johnny and Contribution

題目思路:

抽象一下: n個點、m條邊、點i的點權爲mex(S),S是點i相已經填了的鄰邊的點權構成的集合,輸出一種填點序列。

題目思路:

考慮如果這個圖的每個點都滿足要求,那麼到最後只需要按點權排序之後輸出就行了

就是怎麼check嘛,暴力check就好,假設所有點都填了,那麼mex相鄰點集應該爲當前點權 

這樣check一下就好了。

怎麼說呢...讀題讀了一個小時,可能沒認真讀,寫了10分鐘,唉;

Code:

/*** keep hungry and calm CoolGuang!***/
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll INF=1e18;
const int maxn=1e6+6;
const int mod=1e9+7;
const double eps=1e-15;
inline bool read(ll &num)
{char in;bool IsN=false;
    in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,p;
vector<int>v[maxn];
int c[maxn];
struct node{
    int w,id;
    bool friend operator<(node a,node b){
        return a.w<b.w;
    }
}q[maxn];
ll num[maxn];
vector<int>g;
int vis[maxn];
int main(){
    read(n);read(m);
    for(int i=1;i<=m;i++){
        int x,y;scanf("%d%d",&x,&y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&q[i].w);
        num[i] = q[i].w;
        q[i].id = i;
    }
    for(int i=1;i<=n;i++) c[i] = 1;
    sort(q+1,q+1+n);
    int f = 0;
    q[0].w = 0;
    for(int i=1;i<=n;i++)
        if(abs(q[i].w-q[i-1].w)>1) f = 1;
    for(int i=1;i<=n;i++){
        for(int e:v[i]){
            vis[num[e]] = 1;
            g.push_back(num[e]);
        }
        int t = 1;
        while(vis[t]) t++;
        if(num[i]!=t){
            f = 1;
            break;
        }
        for(int e:g) vis[e] = 0;
        g.clear();
    }
    if(f) printf("-1\n");
    else{
        for(int i=1;i<=n;i++) printf("%d ",q[i].id);
        printf("\n");
    }
    return 0;
}
/**
5 6|9|13 14|17|20 21|
**/

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章