A
用一个布尔数组存储每个字母是否出现过。
我们贪心的想,如果有两个连续的字母,我们选第一个肯定比第二个优
直接扫一遍就行了
#include<bits/stdc++.h>
using namespace std;
int n , k;
char s[100];
bool flag[30];
int read()
{
int sum = 0;char c = getchar();bool flag = true;
while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
if(flag) return sum;
else return -sum;
}
int main()
{
n = read();k = read();
scanf("%s",s+1);
int now = 0 , num = 0;
int len = strlen(s+1);
for(int i = 1;i <= len;++i)
flag[s[i] - 'a' + 1] = true;
for(int i = 1;i <= 26;++i)
{
if(flag[i])
now += i , num++ , i++;
if(num == k) break;
}
if(num < k) printf("-1");
else printf("%d",now);
return 0;
}
B
数据很小,根本不用二分。
直接从小到大枚举答案,对数列排个序,考虑每一个数能贡献多少个组
不满足就输出答案
#include<bits/stdc++.h>
using namespace std;
int n , m;
int a[200];
struct node{
int num , kind;
}sum[200];
int read()
{
int sum = 0;char c = getchar();bool flag = true;
while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
if(flag) return sum;
else return -sum;
}
bool mycmp(node a,node b)
{
return a.num > b.num;
}
bool check(int x)
{
int ss = 0;
for(int i = 1;i <= 100;++i)
ss += (sum[i].num / x);
if(ss >= n) return true;
else return false;
}
int main()
{
n = read();m = read();
for(int i = 1;i <= 100;++i)
sum[i].kind = i;
for(int i = 1;i <= m;++i)
a[i] = read() , sum[a[i]].num++;
sort(sum + 1,sum + 101 , mycmp);
int ans = 0;
for(int i = 1;i <= 100;++i)
if(!check(i)) break;
else ans = i;
printf("%d",ans);
return 0;
}
C
题意有点绕
要耗费最小,我们显然可以发现最后正好用完油
列方程逆推即可
注意a或b为1无解
#include<bits/stdc++.h>
using namespace std;
int n , m;
int a[1100];
int b[1100];
int c[2100];
int read()
{
int sum = 0;char c = getchar();bool flag = true;
while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
if(flag) return sum;
else return -sum;
}
void work()
{
double now = 1.0 * m;bool flag = true;
for(int i = 1;i <= 2 * n;++i)
{
// printf("%d %.8lf\n",c[i],now);
int k = c[i] - 1;
if(c[i] == 1){
printf("-1");
return;
}
now = now + now / (1.0 * k);
}
printf("%.8lf",now - m);
return;
}
int main()
{
n = read();m = read();
for(int i = 1;i <= n;++i)
a[i] = read();
for(int i = 1;i <= n;++i)
b[i] = read();
int k = 0;
c[++k] = b[1];
for(int i = n;i >= 2;--i)
{
c[++k] = a[i];
c[++k] = b[i];
}
c[++k] = a[1];
work();
return 0;
}
D
我们可以先输出n个1或n骗出序列。
然后正常二分就行了
#include<bits/stdc++.h>
using namespace std;
int n , m;
bool flag[40];
int read()
{
int sum = 0;char c = getchar();bool flag = true;
while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
if(flag) return sum;
else return -sum;
}
void work()
{
int l = 1 , r = m;
int k = 0;
while(l + 1< r)
{
k++;
k = k % n;
int mid = (l + r) / 2;
printf("%d\n",mid);
fflush(stdout);
int x = read();
if(!flag[k]) x = -x;
if(x == 0||x == 2) exit(0);
if(x == 1) l = mid + 1;
else r = mid - 1;
}
printf("%d\n",r);
fflush(stdout);
int x = read();
if(x == 0) exit(0);
printf("%d\n",l);
fflush(stdout);
x = read();
if(x == 0) exit(0);
return;
}
int main()
{
m = read();n = read();
for(int i = 1;i <= n;++i)
{
printf("1\n");
fflush(stdout);
int x = read();
if(x == 0) exit(0);
if(x == 1) flag[i] = true;
}
flag[0] = flag[n];
work();
return 0;
}
E
被谷歌翻译坑了cccccc
看成了每种只能用一次,上bitset,仔细一算发现会超时…
如果用无数次就好想了
裴蜀定理。
那我们只要求出GCD,然后枚举倍数不停对k取模即可。
#include<bits/stdc++.h>
using namespace std;
int n , k;
bool flag[101000];
int read()
{
int sum = 0;char c = getchar();bool flag = true;
while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
if(flag) return sum;
else return -sum;
}
int gcd(int a,int b){return (!b) ? a : gcd(b,a%b);}
int main()
{
n = read();k = read();
int now = read();
for(int i = 2;i <= n;++i)
{
int x = read();
now = gcd(now , x);
}
now %= k;
int t = now;
while(!flag[t])
{
flag[t] = true;
t = (now + t) % k;
}
int sum = 0;
for(int i = 0;i < k;++i)
if(flag[i]) sum++;
printf("%d\n",sum);
for(int i = 0;i < k;++i)
if(flag[i]) printf("%d ",i);
return 0;
}