涵盖知识点:暴力、模拟
比赛链接:传送门
A - Johnny and Ancient Computer
题意: 每次只能位移三位以内。不允许右移截断。问最少几次可以使(a)变为(b)。
题解: 不允许截断,所以乘除等价。贪心暴力。
Accept Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll ;
map<ll,int> check;
int main(){
for(int i=0;i<=64;i++)check[1ll<<i]=1;
int t;cin>>t;
while(t--){
ll a,b;
cin>>a>>b;
if(a>b)swap(a,b);
ll ans=0;
while(a<b){
if(a*8<=b)a*=8,ans++;
else if(a*4<=b)a*=4,ans++;
else if(a*2<=b)a*=2,ans++;
else break;
}
cout<<(a==b?ans:-1)<<"
";
}
return 0;
}
B - Johnny and His Hobbies
题意: 问最小的数字(k)使得初始集合的每个数都异或(k)后集合不变。
题解: 直接暴力。
Accept Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll ;
int main(){
int t;cin>>t;
while(t--){
int n;
cin>>n;
vector<int> a(n);
set<int> s;
for(int i=0;i<n;i++){
cin>>a[i];
s.insert(a[i]);
}
//for(auto i:a)cout<<i<<" ";
int ans=-1;
for(int i=1;i<1024;i++){
bool flag=true;
for(int j=0;j<n;j++){
//cout<<a[j]<<" "<<i<<" "<<(a[j]^i)<<"
";
//printf("%d
",s.count(a[j]^i));
if(s.count(a[j]^i)==0){
flag=false;
break;
}
}
if(flag){
ans=i;
break;
}
}
cout<<ans<<"
";
}
return 0;
}
C - Johnny and Another Rating Drop
题意: 考虑二进制下,定义两个数的差值是不同的位数。求(1 到 n)相邻数字的差值的和。
题解: 考虑每一位对总答案的贡献。公式见代码,证明脑补一下应该能脑补出来。
Accept Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll ;
int main(){
int t;cin>>t;
while(t--){
ll n;
cin>>n;
ll ans=0;
while(n){
ans+=n;
n/=2;
}
cout<<ans<<"
";
}
return 0;
}
D - Johnny and Contribution
题意: 每篇博客只能覆盖一个主题,但一个主题可以被多个博客覆盖。博客之间有引用的关系。互相引用的博客不能够覆盖同一主题。对于每一个博客,会选择能够覆盖的最小主题进行覆盖。求顺序完成博客以满足给定的引用关系。
题解: 抽象成图以后根据每个顶点的属性从小到大进行排序。然后依次安排,分别检测所连接的点是否含有相同属性,并且是否覆盖小于该属性的所有正整数即可。
Accept Code:
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int maxn=5e5+10;
int c[maxn];
vector<int> g[maxn];
pii rec[maxn];
int main() {
int n, m;
cin >> n >> m;
for (int i = 0,a,b; i < m; i++) {
cin>>a>>b;
a--,b--;
g[a].push_back(b);
g[b].push_back(a);
}
for (int i = 0,t; i < n; i++) {
cin>>t;
rec[i] = {t,i};
}
sort(rec, rec + n);
for (int i = 0; i < n; i++) {
int node = rec[i].second;
int col = rec[i].first;
set<int> bs;
for (int j : g[node]) {
int ncol = c[j];
if (ncol && ncol < col)
bs.insert(ncol);
if (ncol == col) {
cout << -1 << "
";
return 0;
}
}
if (bs.size() == col - 1)c[node] = col;
else {
cout << -1 <<"
";
return 0;
}
}
for (int i = 0; i < n; i++) {
cout << rec[i].second + 1 << ' ';
}
cout << "
";
}