前言
其中A~C比较简单,就只放代码了;
D1,D2,E会有个人理解
F和G待补
A
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int a[10];
void solve(){
for(int i=1;i<=3;++i) cin >> a[i];
int mx = 0;
for(int i=1;i<=3;++i){
mx = max(mx,a[i]);
}
int cnt = 0;
for(int i=1;i<=3;++i){
if(a[i] == mx) ++cnt;
}
if(cnt == 3){
for(int i=1;i<=3;++i) cout << a[0]+1 << ' ';
cout << '\n';
return;
}
if(cnt == 2){
for(int i=1;i<=3;++i){
cout << mx - a[i] + 1 << ' ';
}
cout << '\n';
return;
}
for(int i=1;i<=3;++i){
if(a[i] == mx) cout << 0 << ' ';
else cout << mx - a[i] + 1 << ' ';
}
cout << '\n';
}
int main(){
std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t;
cin >> t;
while(t--) solve();
return 0;
}
B
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e2 + 10;
char str[N];
void solve(){
cin >> (str+1);
int ans = 1e9;
int n = strlen(str+1);
for(int i=1;i<n;++i){
for(int j=i+1;j<=n;++j){
int now = (str[i]-'0')*10 + (str[j]-'0');
if(now % 25 == 0){
ans = min(ans,n-2-(i-1));
}
}
}
cout << ans << '\n';
}
int main(){
std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t;
cin >> t;
while(t--) solve();
return 0;
}
C
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 4e5 + 10;
int a[N],n,k;
void solve(){
cin >> n >> k;
for(int i=1;i<=k;++i){
cin >> a[i];
}
sort(a+1,a+1+k);
int ans = 0,cat = 0;
for(int i=k;i>=1;--i){
if(cat >= a[i]) break;
++ans;
cat += n-a[i];
}
cout << ans << '\n';
}
int main(){
std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t;
cin >> t;
while(t--) solve();
return 0;
}
D1
因为我们最终要使得所有的数相等,那么我们可以转化一下思路;
我们可以认为,所有的数模某个数,它们都是同余的;
那么我们的任务就变成了求最大的模数是多少;
我们假设模数为 k k k,那么我们让数组中的数两两做差;
这样得到的差值必然是 k k k的倍数(我们就是要减去余数);
比如 x = a k + r , y = c k + r , x − y = ( a − c ) k x=ak+r,y=ck+r,x-y=(a-c)k x=ak+r,y=ck+r,x−y=(a−c)k;
假设这些差值为 d 1 , d 2 , . . . , d y d_1,d_2,...,d_y d1,d2,...,dy
那么答案必然是 g c d ( d 1 , d 2 , . . . , d y ) gcd(d_1,d_2,...,d_y) gcd(d1,d2,...,dy)
也就是说我们想让倍数尽可能小,而模数尽可能大,那么直接用gcd即可;
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e2 + 10;
int a[N];
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
void solve(){
int n;
cin >> n;
for(int i=1;i<=n;++i) cin >> a[i];
bool flag = 1;
for(int i=2;i<=n;++i){
if(a[1] != a[i]) {
flag = 0;
break;
}
}
if(flag){
cout << -1 << '\n';
return;
}
vector<int> ve;
for(int i=1;i<n;++i){
for(int j=i+1;j<=n;++j){
int dif = a[j] - a[i];
dif = dif>=0?dif:-dif;
if(dif != 0) ve.push_back(dif);
}
}
int ans = ve[0];
for(int i=1;i<ve.size();++i) ans = gcd(ans,ve[i]);
cout << ans << '\n';
}
int main(){
std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t;
cin >> t;
while(t--)
solve();
return 0;
}
D2
和上题一个思路,我们想使得一半的数模 k k k同余;
假设差值为 d 1 , d 2 , . . . , d y d_1,d_2,...,d_y d1,d2,...,dy
我们知道每个差值一定是某个数的倍数,而这个数就是模数;
我们想使得这个模数尽可能大,那么只需要枚举差值的因子并取max
即可;
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <ctime>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e2 + 10;
int a[N],n,ans;
map<int,int> mp;
void ck(int x){
mp.clear();
for(int i=1,r;i<=n;++i){
r = ((a[i]%x)+x)%x;
if(++mp[r] >= n/2){
ans = max(ans,x);
break;
}
}
}
void solve(){
mp.clear();
cin >> n;
for(int i=1;i<=n;++i){
cin >> a[i];
++mp[a[i]];
}
for(auto x : mp){
if(x.second >= n/2){
cout << -1 << '\n';
return;
}
}
vector<int> ve;
for(int i=1;i<n;++i){
for(int j=i+1;j<=n;++j){
int dif = a[j] - a[i];
dif = dif>=0?dif:-dif;
if(dif != 0){
ve.push_back(dif);
}
}
}
mp.clear();
ans = 1;
for(auto x : ve){
//最大的可能的贡献是x
//如果x都小于ans,说明它的因子都没用
if(x <= ans) continue;
for(int p=1;p*p<=x;++p){
if(x % p == 0){
// x/p >= p,前者都没用,那后面必然不可能有用的
if(x/p<=ans) break;
ck(x/p);
ck(p);
}
}
}
cout << ans << '\n';
}
int main(){
std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t;
cin >> t;
while(t--)
solve();
return 0;
}
E
我们只需要拓扑排序一下,记录dep
即可;
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 4e5 + 10;
int in[N],n,k,dep[N];
vector<int> G[N];
vector<int> sorted;
void solve(){
cin >> n >> k;
sorted.clear();
for(int i=1;i<=n;++i){
in[i] = dep[i] = 0;
G[i].clear();
}
for(int i=1,u,v;i<=n-1;++i){
cin >> u >> v;
++in[u],++in[v];
G[u].push_back(v);
G[v].push_back(u);
}
queue<int> q;
for(int i=1;i<=n;++i){
if(in[i]==1){
q.push(i);
dep[i] = 1;
}
}
while(!q.empty()){
int u = q.front();
sorted.push_back(u);
q.pop();
for(auto v : G[u]){
--in[v];
if(in[v]==1){
q.push(v);
dep[v] = dep[u] + 1;
}
}
}
int ans = 0;
for(auto x : sorted){
if(dep[x] > k) ++ans;
}
cout << ans << '\n';
}
int main(){
std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t;
cin >> t;
while(t--)
solve();
return 0;
}