题意:
相较于咕咕东,瑞神是个起早贪黑的好孩子,今天早上瑞神起得很早,刷B站时看到了一个序列 ,他对
这个序列产生了浓厚的兴趣,他好奇是否存在一个数 ,使得一些数加上 ,一些数减去 ,一些数不
变,使得整个序列中所有的数相等,其中对于序列中的每个位置上的数字,至多只能执行一次加运算或
减运算或是对该位置不进行任何操作。由于瑞神只会刷B站,所以他把这个问题交给了你!
输入格式
输入第一行是一个正整数 表示数据组数。 接下来对于每组数据,输入的第一个正整数 表示序列 的长
度,随后一行有 个整数,表示序列a 。
输出格式
输出共包含 行,每组数据输出一行。对于每组数据,如果存在这样的K,输出"YES",否则输出“NO”。(输出不包含引号)
输入样例
2
5
1 2 3 4 5
5
1 2 3 4 5
输出样例
NO
NO
思路:
1.模测的时候,递交了也不知道思路对不对。输出的时候与输出样例也相同就递交了,结果结束的时候没有一个测试点过(哭),原来的思路是算出这个数组的平均值,然后数组的每个元素与平均值作差之间作比较,把数值等于平均值的数字排除,如果比较下来发现相同即可。结果不对(微笑脸)
2.后来去看别人的思路发现:输出YES有两种情况:1.全组有一种数字或者两种数字2.全组有三种数字且作差相等即可
(哎,心里悲伤那么大)
代码:
#include
#include
#include
#include
#include
using namespace std;
int t, n, di;
long long a[10010];
long long temp, zl, mid, ri;
int main(void)
{
cin >> t;
while (t--)
{
di = 1;
memset(a, 0, sizeof(a));
//memset(av,0,sizeof(av));
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
sort(a, a + n);
temp = a[0], zl = a[0], mid = a[n - 1], ri = a[n - 1];
if (a[0] == a[n - 1])
{
cout << "YES" << endl;
continue;
}
for (int i = 1; i < n; i++)
{
if (a[i] != temp)
{
if (di == 1)
{
mid = a[i];
}
else if (di == 2)
{
ri = a[i];
}
di++;
temp = a[i];
}
}
if (di == 2)//只有两种值
{
cout << "YES" << endl;
continue;
}
else if (di == 3 && (ri - mid) == (mid - zl))//只有三个数不一样且差值相同
{
cout << "YES" << endl;
continue;
}
else
cout << "NO" << endl;
}
return 0;
}
题意:
给定一个只含26个大写英文字母和’?'的字符串,找出一个连续的且由26个大写字母组成的串,在这个子串中每个字母都只出现一次 '?'可以当做任何字母
如果有,输出最靠左且字典序最小的子串
如果没有 输出"-1"
Input
一个字符串(len<=106)
Output
子串或"-1"
Sample Input 1
ABC??FGHIJK???OPQR?TUVWXY?
Sample Output 1
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Sample Input 2
AABCDEFGHIJKLMNOPQRSTUVW??M
Sample Output 2
-1
思路:
本题的思路类似于滑动窗口,首先判断字符串s的前26个字母,character数组是用来储存字符串中每个元素分别有多少个,例如s[1]=A,对应于character[1]=个数++若s[i]=’?'则cnt++;然后判断character数组中有多少个等于0,que++.
最后判断cnt与que,如果相等则可以用问号代替缺少的元素,如果不相等的话,将右下标右移判断cnt,que同时最左下标往右移判断cnt,que。如果碰到‘\0’则输出-1.
代码:
#include
#include
#include
#include
#include
using namespace std;
char s[1000010];
int character[27];
int que = 0;
int index1 = 0;
char eng[] = { 0,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' };
int cnt = 0;
int main()
{
cin >> s;
for (int i = 0; i < 27; i++)
character[i] = 0;
//cout<<";;;;";
for (int i = 0; i < 26; i++)
{
if (s[i] == '?') cnt++;
else
{
int j = s[i] - 'A' + 1;
character[j]++;
}
}
//cout<<"...."<
for (int i = 1; i < 27; i++)
{
if (character[i] == 0) que++;
}
//cout<
index1 = 25;
//char ans[27];
while (1) {
if (que == cnt)//问号的个数等于0的个数
{
char ans[27];
for (int i = 1; i <= 26; i++)
ans[i] = s[index1 - 26 + i];
int indexb = 0;
char bu[26];
for (int i = 1; i <= 26; i++)
{
if (character[i] == 0)
{
bu[indexb] = eng[i];
indexb++;
}
}
indexb = 0;
for (int i = 1; i <= 26; i++)
{
if (ans[i] == '?')
ans[i] = bu[indexb++];
}
for (int i = 1; i <= 26; i++)
cout << ans[i];
cout << endl;
break;
}
if (s[index1 + 1] == '\0')
{
cout << "-1" << endl;
break;
}
index1++;
if (s[index1] == '?') cnt++;
else
{
int j = s[index1] - 'A' + 1;
character[j]++;
if (character[j] == 1) que--;
}
if (s[index1 - 26] == '?') cnt--;
else
{
int j = s[index1 - 26] - 'A' + 1;
character[j]--;
if (character[j] == 0) que++;
}
}
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
char s[1000010];
int character[27];
int que = 0;
int index1 = 0;
char eng[] = { 0,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' };
int cnt = 0;
int main()
{
cin >> s;
for (int i = 0; i < 27; i++)
character[i] = 0;
//cout<<";;;;";
for (int i = 0; i < 26; i++)
{
if (s[i] == '?') cnt++;
else
{
int j = s[i] - 'A' + 1;
character[j]++;
}
}
//cout<<"...."<
for (int i = 1; i < 27; i++)
{
if (character[i] == 0) que++;
}
//cout<
index1 = 25;
//char ans[27];
while (1) {
if (que == cnt)//问号的个数等于0的个数
{
char ans[27];
for (int i = 1; i <= 26; i++)
ans[i] = s[index1 - 26 + i];
int indexb = 0;
char bu[26];
for (int i = 1; i <= 26; i++)
{
if (character[i] == 0)
{
bu[indexb] = eng[i];
indexb++;
}
}
indexb = 0;
for (int i = 1; i <= 26; i++)
{
if (ans[i] == '?')
ans[i] = bu[indexb++];
}
for (int i = 1; i <= 26; i++)
cout << ans[i];
cout << endl;
break;
}
if (s[index1 + 1] == '\0')
{
cout << "-1" << endl;
break;
}
index1++;
if (s[index1] == '?') cnt++;
else
{
int j = s[index1] - 'A' + 1;
character[j]++;
if (character[j] == 1) que--;
}
if (s[index1 - 26] == '?') cnt--;
else
{
int j = s[index1 - 26] - 'A' + 1;
character[j]--;
if (character[j] == 0) que++;
}
}
return 0;
}
题意:
有一个序列11212312341234512345612345671234567812345678912345678910······
特点为由若干部分组成 每一部分si为1~i所有数字
给出q(q<=500)次查询 每次查询给出一个数字ki(ki<=1018) 请给出序列中第ki个数字
例如 第1项是1,第3项是2,第20项是 5,第38项是2,第56项是0
Input
第一行给出q
接下来2~q+1行 每行一个数字ki
Output
输出包含q行
第i行输出对询问 的输出结果。
Sample Input
5
1
3
20
38
56
Sample Output
1
2
5
2
0
思路:
当初看到这道题的时候只考虑了1—9的情况:算出前n个序列的数字个数,如果大于数字k,则K在第n个序列中,然后再算前x个数的个数,确定K在这个序列中的位置。这个思路我只考虑了1—9的数,当数字是1—10时候,序列个数变为:11、13,15,其实原来到这里就卡了。
之后去看别人写的思路发现,确定k在哪一个部分以及在哪个部分的哪个位置可以用等差数列求前N项和。然后这个查询过程中也可以用到二分查找,查找离K最近的位置。然后K减。思路差不多是这个样子。(真的太厉害了,想到了二分,我完全想不到)
代码:
#include
#include
#include
#include
#include
using namespace std;
long long k, l, r, mid, ans;
int p;
long long have(long long a, int pos)
{
long long wr = 1, ss = 0, s = 0, n = 0, d = 0;//ssum算总长度,sum算在i部分的位置
while (true)
{
wr *= 10;
d++;//公差
if (a > wr - 1)
{
n = wr - wr / 10;
ss += (s + d) * n + n * (n - 1) / 2 * d;
s += n * d;
}
else
{
n = a - wr / 10 + 1;
ss += (s + d) * n + n * (n - 1) / 2 * d;
s += n * d;
break;
}
}
return pos == 1 ? ss : s;
}
int main()
{
cin >> p;
for (int i = 0; i < p; i++)
{
cin >> k;
l = 0;
r = 1e9;
while (l <= r)
{//在ss中找到与k最相近的数
mid = (l + r) / 2;
if (have(mid, 1) < k)
{
ans = mid;
l = mid + 1;
}
else r = mid - 1;
}
k -= have(ans, 1);//在第i部分中的位置
//cout<
l = 0;
r = ans + 1;
while (l <= r)
{
mid = (l + r) / 2;
if (have(mid, 2) < k)
{
ans = mid;
l = mid + 1;
}
else r = mid - 1;
}
//cout<<"???"<
k -= have(ans, 2);
ans++;
string oo = to_string(ans);
printf("%d\n", oo[k - 1] - '0');
}
return 0;
}