这里写目录标题
A - HRZ 的序列
题意:
判断一个数组中的数能否小于4,且构成等差
思路:
利用set直接解决一个数组中不同元素个数的多少,如果<=2,则直接yes,为3时进行判断能否构成等差,大于3直接no。
代码:
#include<iostream>
#include<set>
using namespace std;
int t,n,x,b[3],g;
set<int> a;
int main()
{
cin >>t;
while(t--)
{
a.clear();
g=0;
set<int>::iterator it;
scanf("%d",&n);
while(n--)
{
scanf("%d",&x);
a.insert(x);
}
if(a.size()==1||a.size()==2)
cout << "YES" << endl;
else if(a.size()==3)
{
it=a.begin();
while(it!=a.end())
{
b[g++]=*it;
++it;
}
if(b[0]+b[1]==2*b[2]||b[0]+b[2]==2*b[1]||b[1]+b[2]==2*b[0])
cout << "YES" << endl;
else
cout << "NO" << endl;
}
else
cout << "NO" << endl;
}
}
HRZ学英语
题意:
给定一个字符串,包括26个大写字母以及?,其中?可以代表任何字母,判断是否存在连续26个字符包括所有字母,如果存在找最左边以及字典序最小。
不存在输出-1
思路:
可以用曲尺法的思想进行解题,从前26个开始,将所有的字母以及问号的个数求出来,没往右走一步,则减去左边的那个数,加上右边的那个数,直到所有字母的数量为0或者1,然后找到?所在位置,将为0的字母替换上去,既得最终答案。
代码:
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
char s[1000100];
int a[30];//0表示?
char b[30];
int g=0,l;
char c;
bool find()
{
for(int i=1;i<=26;i++)
{
if(a[i]!=0&&a[i]!=1)
return false;
}
return true;
}
void print()
{
for(int i=1;i<=26;i++)
{
if(a[i]==0)
b[g++]=i;
}
sort(b,b+g);
g=0;
for(int i=1;i<=26;i++)
{
if(s[l+i-1]!='?')
{
cout << s[l+i-1];
}
if(s[l+i-1]=='?')
{
c=b[g++]+64;
cout << c;
}
}
cout << endl;
}
int main()
{
scanf("%s",&s);
int size=strlen(s);
if(size<26)
{
cout << -1 << endl;
return 0;
}
for(int i=0;i<26;i++)
{
if(s[i]=='?')
a[0]++;
else
a[s[i]-64]++;
}
l=0;
if(size==26)
{
if(find())
{print();
return 0;
}
else
{
cout << -1 << endl;
return 0;
}
}
l=1;
while(l)
{
if(s[l-1]=='?')
a[0]--;
else
a[s[l-1]-64]--;
if(s[l+25]=='?')
a[0]++;
else
a[s[l+25]-64]++;
if(find())
{
print();
return 0;
}
l++;
if(l+25==size)
break;
}
cout << -1 << endl;
//cout << a[0] << a[2] << endl;
//cout << s[0] << endl;
return 0;
}
咕咕东的奇妙序列
题意:
类似1121231234…这样的序列给你第k项,求出对应的数字。
思路:
对于直接暴力求解的话,会出现时间复杂度太高,则将这一个序列分为2部分,第一部分为他自己单独一轮,另一部分即为这个数前面轮数所出现数字次数的总和,可以通过一个find函数,将所有的前面的数加起来,或者说是将这一轮数所包含的数字的个数,然后进行二分查找。
第一轮二分查找是找到这个数所在轮数前面所有轮所包含的数字,然后在第二次二分查找时,查找到这个数在这一轮中所处于的位置,然后可以利用snprintf函数,将数字转为字符数组,在找到第k-1项的数字,即为最终结果。
代码:
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int q;
long long k;
int f(int k)
{
for(int i=1;i<=10;i++)
{
for(int j=1;j<=i;j++)
{
k--;
if(k==0)
return j;
}
}
}
long long find(long long int x,int flag)
{
long long sum=0;
int f=0;
long long n=0,a1=0,an=0,d=0;
while(1)
{
if(f==0) f=1;
else f=f*10;
if(x>f*10-1)
{
n=10*f-f;
d++;
a1=an+d;
an=a1+(n-1)*d;
sum=sum+(a1+an)*n/2;
}
else
{
n=x-f+1;
d++;
a1=an+d;
an=a1+(n-1)*d;
sum=sum+(a1+an)*n/2;
break;
}
}
if(flag==1) return sum;
else return an;
}
int main()
{
cin >> q;
for(int w=0;w<q;w++)
{
cin >> k;
if(k<55)
cout << f(k) << endl;
else if(k==55||k==56)
cout << 56-k << endl;
else
{
long long l=0,r=1e9,mid,ans=0;
while(l<=r)
{
mid=(l+r)/2;
if(find(mid,1)>=k)
ans=mid,r=mid-1;
else l=mid+1;
}
k=k-find(ans-1,1);
l=0,r=ans+1;
while(l<=r)
{
mid=(l+r)/2;
if(find(mid,2)>=k)
ans=mid,r=mid-1;
else l=mid+1;
}
k=k-find(ans-1,2);
char a[20];
snprintf(a,sizeof(a),"%lld",ans);
cout << a[k-1] << endl;
}
}
}