Codeforces Round #555 (Div. 3) ABC1C2E

传送门

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;
}

 

展开阅读全文

没有更多推荐了,返回首页