由于备战考试这里先挖坑
A. Happy Birthday, Polycarp! (CF 1277 A)
题目大意
解题思路
(位数-1)*9+首位-1+(n是否大于那个值)
神奇的代码
#include <bits/stdc++.h>
#define MIN(a,b) ((((a)<(b)?(a):(b))))
#define MAX(a,b) ((((a)>(b)?(a):(b))))
#define ABS(a) ((((a)>0?(a):-(a))))
using namespace std;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
void Input(void) {
int ans=0;
int n,m;
int qwq[22];
read(n);
m=n;
int cnt=0;
while(n>9){
m=MIN(m,n%10);
ans+=9;
qwq[++cnt]=n%10;
n/=10;
}
ans+=n-1;
qwq[0]=10;
for(int i=cnt;i>=0;--i) if (qwq[i]>n){++ans;break;} else if (qwq[i]<n) break;
write(ans,'\n');
}
void Solve(void) {}
void Output(void) {}
main(void) {
int kase;
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
read(kase);
for (int i = 1; i <= kase; i++) {
//printf("Case #%d: ", i);
Input();
Solve();
Output();
}
}
B. Make Them Odd (CF 1277 B)
题目大意
解题思路
记录偶数,去重,把每一个偶数一直除以2得到奇数,记录得到该奇数的最大操作次数,最后是出现的所有奇数的操作次数和。
神奇的代码
#include <bits/stdc++.h>
#define MIN(a,b) ((((a)<(b)?(a):(b))))
#define MAX(a,b) ((((a)>(b)?(a):(b))))
#define ABS(a) ((((a)>0?(a):-(a))))
using namespace std;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
unordered_map<int,int> sign;
const int N=2e5+8;
int n,num[N],cnt;
long long ans,an[N];
void Input(void) {
sign.clear();
cnt=0;
read(n);
for(int u,i=1;i<=n;++i){
read(u);
if (((u&1)==0)&&sign[u]==0) {sign[u]=1; num[++cnt]=u;}
}
}
void Solve(void) {
ans=0;
sort(num+1,num+1+cnt);
for(int u,cout,i=cnt;i>=1;--i)
if (sign[num[i]]){
u=num[i];
u>>=1;
cout=1;
while((u&1)==0){
if (sign[u]) sign[u]=0;
u>>=1;
++cout;
}
an[i]=cout;
}
for(int i=cnt;i>=1;--i)
if (sign[num[i]]) ans+=an[i];
}
void Output(void) {
write(ans,'\n');
}
main(void) {
int kase;
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
read(kase);
for (int i = 1; i <= kase; i++) {
//printf("Case #%d: ", i);
Input();
Solve();
Output();
}
}
C. As Simple as One and Two (CF 1277 C)
题目大意
解题思路
先检查是否有twone,把o去掉,然后再检查one和two,把中间字母去掉即可。
神奇的代码
#include <bits/stdc++.h>
#define MIN(a,b) ((((a)<(b)?(a):(b))))
#define MAX(a,b) ((((a)>(b)?(a):(b))))
#define ABS(a) ((((a)>0?(a):-(a))))
using namespace std;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
char one[4]={"one"};
char two[4]={"two"};
char twone[6]={"twone"};
int nxtone[4],nxttwo[4],nxttwone[6];
const int N=2e5+8;
char s[N];
int len,cnt;
int anspos[N];
void makenext(char qaq[],int nxt[],int n){
nxt[0]=0;
int k=0;
for (int i=1;i<n;i++){
while ((k>0)&&(qaq[k]!=qaq[i])) k=nxt[k-1];
if (qaq[k]==qaq[i]) k++;
nxt[i]=k;
}
}
void kmp(char qaq[],int nxt[],char qwq[],int n){
int q=0;
for (int i=0;i<len;i++){
if (qwq[i]=='@') continue;
while ((qwq[i]!=qaq[q])&&(q>0)) q=nxt[q-1];
if (qwq[i]==qaq[q]) q++;
if (q==n) {
if (n==5) {qwq[i-2]='@'; anspos[++cnt]=i-1;}
else {qwq[i-1]='@'; anspos[++cnt]=i;}
}
}
}
void Input(void) {
cnt=0;
scanf("%s",s);
len=strlen(s);
}
void Solve(void) {
kmp(twone,nxttwone,s,5);
kmp(two,nxttwo,s,3);
kmp(one,nxtone,s,3);
}
void Output(void) {
write(cnt,'\n');
for(int i=1;i<=cnt;++i) printf("%d%c",anspos[i],i==cnt?'\n':' ');
if (cnt==0) puts("");
}
main(void) {
int kase;
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
read(kase);
makenext(one,nxtone,3);
makenext(two,nxttwo,3);
makenext(twone,nxttwone,5);
for (int i = 1; i <= kase; i++) {
//printf("Case #%d: ", i);
Input();
Solve();
Output();
}
}
D. Let's Play the Words? (CF 1277 D)
题目大意
解题思路
每个01串按照首位和末位进行分类,共四类,-1的情况即是仅有00和11而无01或10,注意到如果有01或10串翻转得到另一个已有的串,则这两个本身可以搭配,可以忽略,然后统计01和10的数量,翻转的最小的次数即是两者数量差值除以2.
神奇的代码
#include <bits/stdc++.h>
#define MIN(a,b) ((((a)<(b)?(a):(b))))
#define MAX(a,b) ((((a)>(b)?(a):(b))))
#define ABS(a) ((((a)>0?(a):-(a))))
using namespace std;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
const int N=2e5+8;
int num[4],s01[N],s10[N];
int n,l,c0,c1;
string s,ss;
unordered_map<string,pair<int,bool>> qwq;
void Input(void) {
qwq.clear();
num[0]=num[1]=num[2]=num[3]=0;
c0=c1=0;
cin>>n;
for(int i=1;i<=n;++i){
cin>>s;
if (s[0]==s[s.size()-1]) {qwq[s]=make_pair(i,1);continue;}
ss=s;
reverse(s.begin(),s.end());
if (qwq[s].second==1) {qwq[s].second=0;++num[2];++num[3];continue;}
qwq[ss]=make_pair(i,1);
}
}
void Solve(void) {
for(auto v:qwq){
if (v.second.second==1){
const char *ss=v.first.c_str();
l=strlen(ss);
if (l==1) ++num[ss[0]-'0'];
else{
if (ss[0]=='0'&&ss[l-1]=='0') ++num[0];
else if (ss[0]=='0'&&ss[l-1]=='1') ++num[2],s01[++c0]=v.second.first;
else if (ss[0]=='1'&&ss[l-1]=='0') ++num[3],s10[++c1]=v.second.first;
else ++num[1];
}
}
}
if (num[2]==0&&num[3]==0&&num[0]!=0&&num[1]!=0) cout<<"-1"<<endl;
else {
int qwq=ABS(num[2]-num[3]);
qwq/=2;
cout<<qwq<<endl;
if (num[2]>num[3]) for(int i=1;i<=qwq;++i) cout<<s01[i]<<(i==qwq?'\n':' ');
else for(int i=1;i<=qwq;++i) cout<<s10[i]<<(i==qwq?'\n':' ');
if (qwq==0) cout<<'\n';
}
}
void Output(void) {}
main(void) {
ios::sync_with_stdio(false);
int kase;
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
cin>>kase;
for (int i = 1; i <= kase; i++) {
//printf("Case #%d: ", i);
Input();
Solve();
Output();
}
}