A
题意:给你一个数每次加一 若末尾有0则消除 问通过这操作总共能得到多少个不同的数
#include <bits/stdc++.h>
#define ll long long
using namespace std;
map<ll,ll>mp;
int main()
{
ll n;
cin>>n;
ll ans=0;
while(n)
{
if(mp[n]==1)
{
break;
}
if(mp[n]==0)
{
mp[n]=1;
ans++;
}
n++;
while(n%10==0)
{
//cout<<"--"<<n<<endl;
n/=10;
}
}
cout<<ans<<endl;
return 0;
}
B
给你一个n位长的数 问把连续n位进行转换(可为空) 得到的最大的数是多少
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[200010];
int b[15];
int main()
{
int n;
cin>>n;
string s;
cin>>s;
for(int i=1;i<=n;i++)
{
a[i]=s[i-1]-'0';
}
for(int i=1;i<=9;i++)
{
cin>>b[i];
}
int flag=0;
for(int i=1;i<=n;i++)
{
if(a[i]<b[a[i]])
{
if(flag==0||flag+1==i)
{
a[i]=b[a[i]];
flag=i;
continue;
}
else
break;
}
if(a[i]>b[a[i]]&&flag!=0)
{
break;
}
if(a[i]==b[a[i]])
{
if(flag==0)
continue;
else
flag=i;
}
}
for(int i=1;i<=n;i++)
{
cout<<a[i];
}
cout<<endl;
return 0;
}
C1
给你n个不同的数 每次从两头取出任意一个 每次取出的数都要比上次取出的大 也就是 问最多能取出多少个
用 deque 来模拟
#include <bits/stdc++.h>
#define ll long long
using namespace std;
deque<int>q;
int main()
{
int n;
cin>>n;
string s;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
q.push_back(x);
}
int x=0;
while(q.size()!=0)
{
if(q.front()<=q.back()&&q.front()>x)
{
x=q.front();
s+='L';
q.pop_front();
continue;
}
if(q.front()<=q.back()&&q.front()<x&&q.back()>x)
{
x=q.back();
s+='R';
q.pop_back();
continue;
}
if(q.front()>=q.back()&&q.back()>x)
{
x=q.back();
s+='R';
q.pop_back();
continue;
}
if(q.front()>=q.back()&&q.front()>x&&q.back()<x)
{
x=q.front();
s+='L';
q.pop_front();
continue;
}
break;
}
cout<<s.size()<<endl;
cout<<s<<endl;
return 0;
}
C2
和c1的唯一区别是 n个数中可能存在相同的数
#include <bits/stdc++.h>
#define ll long long
using namespace std;
/*4 2 2 2 3*/
deque<int>q;
int main()
{
int n;
cin>>n;
string s;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
q.push_back(x);
}
int x=0;
while(q.size()!=0)
{
//cout<<q.front()<<" "<<q.back()<<x<<endl;
if(q.front()<q.back()&&q.front()>x)
{
// cout<<1<<endl;
x=q.front();
s+='L';
q.pop_front();
continue;
}
if(q.front()<q.back()&&q.front()<=x&&q.back()>x)
{
// cout<<2<<endl;
x=q.back();
s+='R';
q.pop_back();
continue;
}
if(q.front()>q.back()&&q.back()>x)
{
// cout<<3<<endl;
x=q.back();
s+='R';
q.pop_back();
continue;
}
if(q.front()>q.back()&&q.front()>x&&q.back()<=x)
{
// cout<<4<<endl;
x=q.front();
s+='L';
q.pop_front();
continue;
}
if(q.front()==q.back())// 相等时直接特判一下就行了
{
deque<int>q1(q);
string s1=s,s2=s;
int xx=x;
//一直选左
while(q1.front()>xx)
{
xx=q1.front();
s1+='L';
q1.pop_front();
if(q1.size()==0)
{
break;
}
}
//一直向右
deque<int>q2(q);
xx=x;
while(q2.back()>xx&&q2.size()!=0)
{
xx=q2.back();
s2+='R';
q2.pop_back();
if(q2.size()==0)
{
break;
}
}
if(s1.size()<=s2.size())
{
cout<<s2.size()<<endl;
cout<<s2<<endl;
}
if(s1.size()>s2.size())
{
cout<<s1.size()<<endl;
cout<<s1<<endl;
}
return 0;
}
break;
}
cout<<s.size()<<endl;
cout<<s<<endl;
return 0;
}
E
给你两个数组a,b 分别有n个数 将b中数的位置可随意变 问怎样排才能使 (b[i]-a[i])%n 的总和最小
注意前提条件:0≤ai<n0≤ai<n 并且 0≤bi<n0≤bi<n。那么,我们可以在aiai中任取一个数进行分析,发现为满足字典序最小,在bb中找到n−ain−ai就是最优解。
接下来分析bb,在bb中是不一定找得到n−ain−ai的。所以需要分析如何找到此情况下的最优解。
假设ai=3ai=3,n=4n=4,那么bibi对应的最优情况是bi=1bi=1,可以把所有bibi的所有取值情况分析以下:
bi=0bi=0 (ai+bi)%n=3(ai+bi)%n=3
bi=1bi=1 (ai+bi)%n=0(ai+bi)%n=0
bi=2bi=2 (ai+bi)%n=1(ai+bi)%n=1
bi=3bi=3 (ai+bi)%n=2(ai+bi)%n=2
应该已经发现了规律了,就是以n−ain−ai为起点的一个循环。那么我们只要每次保证贪心取最小就可以了,这里需要运用multisetmultiset进行复杂度优化,但一定要注意查找的时候不能用findfind而要用lower_boundlower_bound,这样就可以解决了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
int n,a[maxn],x;
multiset<int>s;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
cin>>x;
s.insert(x);
}
// multiset<int>::iterator it;
for(int i=1;i<=n;i++)
{
auto it = s.lower_bound(n-a[i]);
if(it == s.end())it=s.begin();
printf("%d ",(a[i]+*it)%n);
s.erase(it);// 删迭代器
}
return 0;
}