A. Square String?(字符串)
题目大意:
给出一个字符串 s s s,问字符串 s s s是否是某个字符串 s 1 s_1 s1的双倍
eg. a b a b abab abab 是 a b ab ab的双倍
题解:
先判长度是否是偶数。
如果是偶数再从中间截取,如果两半相等即 Y E S YES YES否则 N O NO NO
#include <iostream>
using namespace std;
void sove(){
string s;
cin>>s;
if(s.size()&1){cout<<"NO\n";return ;}
string s1=s.substr(0,s.size()/2);
string s2=s.substr(s.size()/2);
if(s1==s2)
cout<<"YES\n";
else cout<<"NO\n";
}
int main(void){
int _=1;
cin>>_;
while(_--)sove();
return 0;;
}
B. Squares and Cubes(数学)
题意:
每组数据给出一个 n n n
求1到 n n n中的平方数( x 2 x^2 x2)和立方数( x 3 x^3 x3)的个数
题解1:
用set去重,遍历存储每个数字即可
#include <iostream>
#include <set>
#define int long long
using namespace std;
int ans1e9=32591;
int ans1e8=10443;
int ans1e7=3363;
void sove(){
int n;
cin>>n;
int all=0;
set<int>s;
for(int i=1;i*i<=n;i++){
s.insert(i*i);
if(i*i*i<=n)
s.insert(i*i*i);
}
cout<<s.size()<<endl;
}
signed main(void){
int _=1;
cin>>_;
while(_--)sove();
return 0;
}
题解2:
2的倍数的个数+3的倍数的个数-6的倍数的个数
缘由:2和3的倍数为6
#include <iostream>
#include <vector>
using namespace std;
void sove();
void sove(){
int n;cin>>n;
int ans2=0,ans3=0,ans6=0;
for(int i=1;i*i<=n;i++)ans2++;
for(int i=1;i*i*i<=n;i++)ans3++;
for(int i=1;i*i*i*i*i*i<=n;i++)ans6++;
cout<<ans2+ans3-ans6<<endl;
}
int main(void){
int _=1;
cin>>_;
while(_--)sove();
return 0;
}
C. Wrong Addition(模拟)
题意:
给出一个特殊的加法,按位加,并且无进位,并且直接往高位添加
eg.17236+3465 = 17236 + 03465 =1106911
6+5=11
3+6=9
2+4=6
7+3=10
1+0=1
1 10 6 9 11
如果 a + b = c a+b=c a+b=c
给出 a , c a,c a,c求 b b b
题解1:
按位模拟即可,注意-1的情况,个位相加不可能大于18
#include <iostream>
#include <vector>
#define end {cout<<-1<<endl;return ;}
using namespace std;
void sove();
void sove(){
string a,b;cin>>a>>b;
vector<int>A,B;
vector<int>c;
for(int i=a.size()-1;i>-1;i--)A.emplace_back(a[i]-'0');
for(int i=b.size()-1;i>-1;i--)B.emplace_back(b[i]-'0');
int j=0;
for(int i=0;i<B.size();i++,j++){
int x;
if(j<A.size())
x=A[j];
else x=0;
int y=B[i];
if(x<=y){
c.emplace_back(y-x);
}
else {
y += B[++i]*10;
if(y>=20||y<10)end
else{
c.emplace_back(y-x);
}
}
}
if(j<=A.size()-1) end
else{
while(c.size()>1&&c.back()==0)c.pop_back();
for(int i=c.size()-1;i>-1;i--)cout<<c[i];
cout<<endl;
}
}
int main(void){
int _=1;
cin>>_;
while(_--)sove();
return 0;
}
题解2:
#include <iostream>
#include <vector>
#define int long long
#define end {cout<<-1<<'\n';return;}
using namespace std;
void sove();
void sove(){
int a,c;
cin>>a>>c;
vector<int>v;
while(a){
int x=a%10;//取位
int y=c%10;
if(y>=x){
v.emplace_back(y-x);
}
else{
c/=10;
y = y + (c%10)*10;
if(y>18||y<10)end
else{
v.emplace_back(y-x);
}
}
a/=10;
c/=10;
}
while(c){v.emplace_back(c%10);c/=10;}//放位
while(v.size()>1&&v.back()==0)v.pop_back();//去高位0
for(int i=v.size()-1;i>-1;i--)cout<<v[i];
cout<<'\n';
}
signed main(void){
int _=1;
cin>>_;
while(_--)sove();
return 0;
}
E. MEX and Increments(贪心)
题意:
总和:你可以选择任意一个下标 j j j将数组该下标的数+1
你可以操作任意次
数组有一个 M E X MEX MEX值,是不存在该数组中的所有数中的最小非负整数
每次测试给一个 n n n
再给一个长度为 n n n的数组
问MEX从 0 − > n 0->n 0−>n,所需的最小操作是多少,如果不能输出-1
题解:
记录每个数字的个数
从0遍历到n,每次记录个数大于1的数,消除当前个数a[i],再加上补全前面的全部数的操作数。
如果遇到个数为0的数,取最近记录个数大于1的数,将其取一个过来即可,操作数加上总和
#include <iostream>
#include <vector>
#define int long long
#define end {cout<<-1<<'\n';return;}
using namespace std;
struct node{
int x,y;
//x 数
//y 个数
};
void sove();
void sove(){
int n;cin>>n;
vector<int>a(n+1,0);
for(int i=0;i<n;i++){
int num; cin>>num;
a[num]++;
}
vector<node>v;
int flag=0;
int sum=0;
for(int i=0;i<=n;i++){
if(flag){
cout<<-1<<' ';
continue;
}
if(a[i]>1){
node nd;
nd.x=i;
nd.y=a[i]-1;
v.emplace_back(nd);
}
cout<<a[i]+sum<<' ';
if(a[i]==0){
if(v.empty()){
flag=1;
//cout<<-2<<' ';
continue;
}
sum+=i-v.back().x;
v.back().y--;
if(v.back().y==0)v.pop_back();
}
}
cout<<'\n';
}
signed main(void){
int _=1;
cin>>_;
while(_--)sove();
return 0;
}
一开始的TLE代码:
每次需要重复回溯导致TLE!
#include <iostream>
#include <vector>
#define end {cout<<-1<<endl;return ;}
using namespace std;
inline int read() {
int res = 0, f = 1;
char c;
while ((c = getchar()) < '0' || c > '9') if ('-' == c) f = -1; else if (EOF == c) exit(0);
do res = (res << 1) + (res << 3) + (c ^ 48); while ((c = getchar()) >= '0' && c <= '9');
return res * f;
}
void sove();
void sove(){
int n=read();
vector<int>a(n+1,0);
for(int i=0;i<n;i++){
int num=read();
a[num]++;
}
int flagans=0,flagflag=0;
int sum=0;
for(int i=0;i<=n;i++){
sum+=a[i];
//if(i)
sum--;
if(sum<=0&&flagans==0) { flagans = i;flagflag=1; }
}
int flag=0;
int geshi=1;
for(int i=0;i<=n;i++){
int all=0;
int ans=0;
int anssum=0;
ans=a[i];
if(flag!=1)
for(int j=i-1;j>=0;j--){
if(a[j]==0)anssum++;
if(a[j]>1)anssum =max((int)0,anssum-(a[j]-1));
if(j!=0)
all += anssum ;
//if(all>a[j])flag=1;
}
if(anssum>0)flag=1;
ans+=all;
//if(flagflag&&i==flagans)flag=1;
if(flag) {
if(geshi)cout << -1;
else cout<<' '<<-1;}
else{
if(geshi)cout << ans;
else cout<<' '<<ans;
}
geshi=0;
}
cout<<'\n';
}
int main(void){
int _=1;
_=read();
while(_--)sove();
return 0;
}