首先
Cue一下隊友鏈接:
核心選手:https://me.csdn.net/qq_43559193
核心選手:https://me.csdn.net/weixin_43916298
比賽鏈接:https://codeforces.ml/contest/1362
目錄
A. Johnny and Ancient Computer
C. Johnny and Another Rating Drop
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,這個題基本就完事了
之後寫一個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|
**/