A. Elections
题意
3个人各有一个票数,问每个人票数严格大于其他人还需要多少票
思路
三个数排序一下,如果这个人的票数是最多的没有人和他相同就输出0,有人和他一
样大就输出1,如果票数不是最多的就输出最大减去他的票数加一。
ac代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int,int> PII;
const int maxn=1e6+10;
const double eps=1e-5;
int n;
int a[maxn];
int b[maxn];
int main(){
int t; scanf("%d",&t);
while(t--){
scanf("%d%d%d",&a[0],&a[1],&a[2]);
b[0] = a[0],b[1] = a[1], b[2] = a[2];
sort(a, a + 3);
if(b[0] != a[2]){
printf("%d ",a[2] - b[0] + 1);
}else if(a[1] == a[2]){
printf("1 ");
}else{
printf("%d ",0);
}
if(b[1] != a[2]){
printf("%d ",a[2] - b[1] + 1);
}else if(a[1] == a[2]){
printf("1 ");
}else{
printf("%d ",0);
}
if(b[2] != a[2]){
printf("%d ",a[2] - b[2] + 1);
}else if(a[1] == a[2]){
printf("1 ");
}else{
printf("%d",0);
}
printf("\n");
}
return 0;
}
B. Make it Divisible by 25
题意
给你一个数要你删除一些数字后能被25整除,问最少删除多少个数字。
思路
能被25整除的数后缀一定是25,50,75,00。所以找第一次出现这些后缀需要删除
的最小次数。
ac代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int,int> PII;
const int maxn=1e6+10;
const double eps=1e-5;
int main(){
int t; scanf("%d",&t);
while(t--){
string s;
cin >> s;
int k = s.size() - 1;
int flag = 0;
int ans = 0x3f3f3f3f;
for(int i = k; i >= 0; i --){
if(s[i] == '5'){
flag = 1;
}
if(s[i] == '2' && flag == 1){
ans = min(ans,k - i - 1);
break;
}
}
flag = 0;
for(int i = k; i >= 0; i --){
if(s[i] == '0'){
flag = 1;
}
if(s[i] == '5' && flag == 1){
ans = min(ans,k - i - 1);
break;
}
}
flag = 0;
for(int i = k; i >= 0; i --){
if(s[i] == '5'){
flag = 1;
}
if(s[i] == '7' && flag == 1){
ans = min(ans,k - i - 1);
break;
}
}
flag = 0;
for(int i = k; i >= 0; i --){
if(s[i] == '0' && flag == 1){
ans = min(ans,k - i - 1);
break;
}
if(s[i] == '0'){
flag = 1;
}
}
printf("%d\n",ans);
}
return 0;
}
C. Save More Mice
题意
一只猫在0的位置,有多老鼠分布在一道n - 1的为值,每次一只老鼠移动一次然后
猫移动,问最多又多少只老鼠可以跑到n点。
思路
每次移动最后一只老鼠
ac代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int,int> PII;
const int maxn=1e6+10;
const double eps=1e-5;
int a[maxn];
int main(){
int t; scanf("%d",&t);
while(t--){
int n,k; scanf("%d%d",&n,&k);
for(int i = 1; i <= k;i ++){
scanf("%d",&a[i]);
}
sort(a + 1, a + 1 + k);
int ans = 0;
int now = 0;
for(int i = k; i >= 1; i --){
if(a[i] > now){
ans++;
now = now + n - a[i];
}else{
break;
}
}
printf("%d\n",ans);
}
return 0;
}
D1. All are Same
题意
给一串数a[i],没吃可以选一个a[i]减去k,问最大的k是多少,无限大输出-1
思路
如果变为相同最后肯定是变为最小的,找所有数变为最小的所需要的k的gcd
ac代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int,int> PII;
const int maxn=1e6+10;
const double eps=1e-5;
int a[maxn];
int main(){
int t; scanf("%d",&t);
while(t--){
int n; scanf("%d",&n);
int flag = 0;
for(int i = 1; i <= n; i ++){
scanf("%d",&a[i]);
}
for(int i = 1; i <= n;i ++){
if(a[i] != a[1]) flag = 1;
}
if(flag == 0){
printf("-1\n");
continue;
}
sort(a + 1, a + 1 + n);
int ans = -1;
for(int i = 2; i <= n; i ++){
if(a[i] == a[i - 1]) continue;
int k = a[i] - a[i - 1];
if(ans == -1){
ans = k;
}else{
ans = __gcd(k, ans);
}
}
printf("%d\n",ans);
}
return 0;
}
D2. Half of Same
题意
和D1一样不过要求至少有一半的ai变为一样
思路
枚举最小会变到多少,然后算出其他数到这个数的差,k值一定就是这个差的因数对
k因数分解就可以得到所有可能k得取值,然后重大到小枚举k的取值,看有多少个差
的因数含k,大于n / 2 - 1的话就是一个可能答案,最后取最大值,还有一些细节
看代码。
ac代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int,int> PII;
const int maxn=1e6+10;
const double eps=1e-5;
unordered_map<int,int> e;
int a[maxn];
priority_queue<int> qq;
int main(){
int t; scanf("%d",&t);
while(t--){
int n; scanf("%d",&n);
for(int i = 1; i <= n; i ++){
scanf("%d",&a[i]);
}
sort(a + 1,a + 1 + n);
int cnt = 1;
for(int i = 2; i <= n; i ++){
if(cnt >= n / 2) break;
if(a[i] == a[i - 1]){
cnt ++;
}else{
cnt = 1;
}
}
if(cnt >= n / 2){
printf("-1\n");
}else{
int ans = 0;
for(int i = 1; i <= n / 2 + 1; i ++){
int cnt = 1;
for(int j = i + 1; j <= n; j ++){
if(a[j] == a[i]) cnt ++;
}
for(int j = i + 1; j <= n; j ++){
int p = a[j] - a[i];
if(p == 0){
continue;
}else{
for(int i = 1; i <= p / i; i ++){
if(p % i == 0){
if(e[i] == 0){
qq.push(i);
}
if(e[p / i] == 0){
qq.push(p / i);
}
e[i] ++;
if(i == p / i) continue;
e[p / i] ++;
}
}
}
}
while(!qq.empty()){
int t = qq.top();
qq.pop();
if(e[t] >= n / 2 - cnt) {
ans = max(ans, t);
break;
}
}
while(!qq.empty()){
qq.pop();
}
e.clear();
}
printf("%d\n",ans);
}
}
return 0;
}
E. Gardener and Tree
题意
问一棵树删去k次叶子节点后还剩多少个点,每次删除是散去所有的叶子节点。
思路
记录下每个点的连接,和入度,如果入度为一就进入队列,删除时把队列里的节点
拿出来,跟新与他相连的节点入度减一。
ac代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int,int> PII;
const int maxn=1e6+10;
const double eps=1e-5;
vector<int> g[maxn];
int ru[maxn];
int vis[maxn];
queue<int> now;
int main(){
int t; scanf("%d",&t);
while(t--){
int n,k; scanf("%d %d",&n,&k);
for(int i = 1; i <= n; i ++){
g[i].clear();
ru[i] = 0;
}
while(!now.empty()){
now.pop();
}
for(int i = 1; i < n;i ++){
int x,y; scanf("%d %d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
ru[x] ++;
ru[y] ++;
}
for(int i = 1; i <= n; i ++){
if(ru[i] == 1) now.push(i);
}
if(n == 1) now.push(1);
int ans = n;
while(k > 0){
if(now.empty()) break;
int o = now.size();
ans = ans - o;
for(int i = 0; i < o; i ++){
int q = now.front();
now.pop();
for(int j = 0; j < g[q].size(); j ++){
ru[g[q][j]] --;
if(ru[g[q][j]] == 1){
now.push(g[q][j]);
}
}
}
k --;
}
printf("%d\n",ans);
}
return 0;
}