week8模拟

A:HRZ序列
问题描述:
在这里插入图片描述思路:
(略微不好意思一下,截图截长了),这道题显而易见输入的数据中若有超过三个的不同数字则不可能有答案,所以先sort一下排排序,然后记录有多少个不同的数字,若大于三直接输出NO,如果小于三则必定有因为若为偶数取两个数的平均数即可,若为奇数则一个数直接加另一个不变,若等于三则判断最小值与中间值的差是否等于最大值与中间值的差。

#include <iostream>
#include<algorithm>
int t,n;
using namespace std;
void cs()
{
	cin>>t;
	for(int i=1;i<=t;i++)
	{
		cin>>n;
		long long *A=new long long[n+10];
		for(int i1=0;i1<n;i1++)
		{
			cin>>A[i1];
		}
		sort(A,A+n);
		long long a1=A[0],n1=1,a2;
		long long *A1=new long long[n+10];
		A1[0]=A[0];
		for(int i1=1;i1<n;i1++)
		{
			a2=A[i1];
			if(a2!=a1)
			{
				A1[n1]=A[i1];
				n1++;
			}
			a1=a2;
		}
		if(n1>3)
		{
			if(i!=t)
			{
				cout<<"NO"<<endl;
			}
			else
			{
				cout<<"NO";
			}
		}
		if(n1<3)
		{
			if(i!=t)
			{
				cout<<"YES"<<endl;
			}
			else
			{
				cout<<"YES";
			}
			
		}
		if(n1==3)
		{
			if((A1[1]-A1[0])==(A1[2]-A1[1]))
			{
				if(i!=t)
				{
					cout<<"YES"<<endl;
				}
				else
				{
					cout<<"YES";
				}
				
			}else
			{
				if(i!=t)
				{
					cout<<"NO"<<endl;
				}
				else
				{
						cout<<"NO";
				}
			
			}
		}
	}
}

int main(int argc, char** argv) 
{
	cs();
	return 0;
}

B:HRZ学英语
问题描述:
在这里插入图片描述思路:
若为26个字母则直接判断是否有重复的字母(数组A对应26个字母),若有重复的字母直接输出-1,碰到问号的时候跳过不管,然后遍历数组A,记录里面为0的位置到数组A1,若符合输出条件,不为?输出原字符串,若为?则从最小地方输出A1中存储的字符,这样就是最小字典序。
若大于26个字母则依次取出26个字母进行判断即可,和第一种情况差别不大。

#include <iostream>
#include<string.h>
using namespace std;
string s;
void cs()
{
	int A[30],A1[30];
	memset(A,0,sizeof(A));
	memset(A1,0,sizeof(A1));
	cin>>s;
	int n=s.size();
	int n1=0;//记录? 
	
	if(n==26)
	{
		bool ans=true;
		for(int i=0;i<n;i++)
		{
			if(s[i]!='?')
			{
		    	int a=s[i]-'A';
		    	A[a]++;
		    	if(A[a]>1)
				{
					ans=false;
	                cout<<"-1";
					return;			
				}				
			}
		}
		int xx=0,xx1=0;
		for(int i=0;i<26;i++)
		{
			if(A[i]==0)
			{
				A1[xx]=i;xx++;
			}
		}
		if(ans)
		{
			for(int i=0;i<n;i++)
			{
				if(s[i]!='?')
				{
					cout<<s[i];
				}else
				{
					char b=A1[xx1]+'A';xx1++;
					cout<<b;
				}
			}
		}
	}
	int yy=0;
	if(n>26)
	{

		bool ans1=true;
	while((yy+26)<=n)
	{
				bool ans=true;
			memset(A,0,sizeof(A));
	        memset(A1,0,sizeof(A1));
		string s1=s.substr(yy,26);
	    yy++;
		for(int i=0;i<26;i++)
		{
			if(s1[i]!='?')
			{
		    	int a=s1[i]-'A';
		    	A[a]++;
		    	if(A[a]>1)
				{
					ans=false;
					break;		
				}				
			}
		}
		int xx=0,xx1=0;
		for(int i=0;i<26;i++)
		{
			if(A[i]==0)
			{
				A1[xx]=i;xx++;
			}
		}
		if(ans)
		{
			ans1=false;
			for(int i=0;i<26;i++)
			{
				if(s1[i]!='?')
				{
					cout<<s1[i];
				}else
				{
					char b=A1[xx1]+'A';xx1++;
					cout<<b;
				}
			}
			return;
		}
		if((yy+25)==n)
		{
			if(ans1)
			{
				cout<<"-1";
			}
		}
	}
	}
}
int main(int argc, char** argv) 
{
	cs();
	return 0;
}

C:咕咕东的奇妙序列
问题描述:

在这里插入图片描述思路:
刚开始写的不能满足所需,只能到第六个测试点。
这道题是二分的应用并且比较麻烦,先通过二分判断属于哪个分组中(1到i属于一组),然后计算在这个组中是第几位,再次二分,然后再次二分判断属于几位数,计算在这树中的第几位,输出。

#include<iostream>
#include<string.h>
#include<string>
using namespace std;
long long int vis[4000000], ans[4000000];long long int h=1, j=0, k=0, l;
long long js1(long long int x, long long int y)
{
	long long r = 0, e = x;
	
		while (e)
		{
			r++;
			e /= 10;
//			cout << r << "  " << e << endl;
		}
		r = r - y + 1;
		for (long long int i = 1; i < r; i++)
		{
			x =x/ 10;
	     }
//		cout << x << endl;
		return x % 10;
}
long long js(long long int x)
{
	long long int h=x, j=0, k=0, l=1, m=0, n;
	while (h >= 10)
	{
		h =h/ 10;
		l = l * 10;
		n = l - l / 10;
		m++;
		j = j + n * (k + m) + n * (n - 1) / 2 * m;
		k = k + n * m;
	}
	n = x - l + 1;
	m++;
	j = j + n * (k + m) + n * (n - 1) / 2 * m;
//	cout << j << "   dddd" << endl;
	return j;
}
void cs()
{
	int t;
	cin >> t;
	long long int x;
	vis[1] = 9, ans[1] = 1; h = 1;
	for (int i = 2; i <= 17; i++)
	{
		h = h * 10;
		vis[i] = vis[i - 1] + h * 9 * i;
	}
	for (int i = 2; i <= 19; i++)
	{
		ans[i] = ans[i - 1] * 10;
	}
	for (int i = 0; i < t; i++)
	{
		cin >> x;
		if (x == 1)
		{
			cout << 1 << endl;
		}
		else
		{
			long long left = 0, right = 1e9, mid;
			while (left <= right)
			{
				mid = (left + right) / 2;
				h = js(mid);
		//		cout << h << "  " << mid << "  " << endl;
				if (h < x)
				{
					k = mid;
					left = mid + 1;

				}
				else
				{
					right = mid - 1;
				}
		//		cout << h << "  " << mid << "  " << left << "  " << right << endl;
			}
		//	cout << " dddd " << k << endl;
			h = js(k);
			x = x - h;
	//		cout << "l: " << l << "  " << "h: " << h << "  " <<"k: "<<k<< endl;
			if (x == 1)
			{
				cout << 1 << endl; continue;
			}
			left = 1; right = 17,mid;
			while (left <= right)
			{
				mid = (left + right) / 2;
				if (vis[mid] >= x)
				{
					h = mid;
					right = mid - 1;
				}
				else
				{
					left = mid + 1;
				}
			}
			x = x - vis[h - 1];
			long long int A1 = x / h; 
			long long int A2 = x % h;
			if (A2 == 0)
			{
				A2 = A2 + h;
			}
			else
			{
				A1++;
			}
			long long ff = js1(ans[h] - 1 + A1, A2);
//			cout << "ans: "<<ans[h]<<"  "<<"h: " << h << "  " << "A1: " << A1 << "  " << "A2: " << A2 << "  " << endl;
			cout << ff<< endl;;
		}
	}
}
int main()
{
	cs();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值