真的好生气,做题的时候codeblocks崩了五次,一运行就显示无响应了,原本写出c题想要调试根本没法稿,给我气的呀,到最后还是没交上,今天早上早早的交了一发直接过了(本人是菜逼,平时div2就两题的水平,能做三题已经是非常稀有了此时大佬们投来鄙视的目光),唉......
A. Mark the Photographer
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Mark is asked to take a group photo of 2n2n people. The ii-th person has height hihi units.
To do so, he ordered these people into two rows, the front row and the back row, each consisting of nn people. However, to ensure that everyone is seen properly, the jj-th person of the back row must be at least xx units taller than the jj-th person of the front row for each jj between 11 and nn, inclusive.
Help Mark determine if this is possible.
Input
The first line contains one integer tt (1≤t≤1001≤t≤100) — the number of test cases. Each test case consists of two lines.
The first line of each test case contains two positive integers nn and xx (1≤n≤1001≤n≤100, 1≤x≤1031≤x≤103) — the number of people in each row and the minimum difference Mark wants.
The second line of each test case contains 2n2n positive integers h1,h2,…,h2nh1,h2,…,h2n (1≤hi≤1031≤hi≤103) — the height of each person in units.
Note that the sum of nn over all test cases is not bounded.
Output
For each test case, print a single line containing "YES" if Mark could arrange people satisfying his condition and "NO" otherwise.
You may print each letter in any case (for example, YES, Yes, yes, yEs will all be recognized as positive answers).
Example
input
Copy
3 3 6 1 3 9 10 12 16 3 1 2 5 2 2 2 5 1 2 8 6output
Copy
YES NO YESNote
In the first test case, one possible order is to have the third, fifth, and sixth person on the back row and the second, first, and fourth on the front row. The heights of the people will look like this.
Back 9 12 16 Front 3 1 10
思路:比较简单,直接将整个序列sort一下,然后用双指针法,一个i指向1,一个j指向n+1,然后for循环,判断a[j]-a[i]是否大于等于k,如果不的话就break,如果是的话就i++,j++;
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t,i,j,n,m;
int a[220];
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
for(i=1;i<=2*n;i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+1+2*n);
for(i=1,j=n+1;i<=n;i++,j++)
{
if(a[j]-a[i]<m)
{
break;
}
}
if(i<=n)
printf("NO\n");
else
printf("YES\n");
}
return 0;
}
B. Mark the Dust Sweeper
time limit per test
1.5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Mark is cleaning a row of nn rooms. The ii-th room has a nonnegative dust level aiai. He has a magical cleaning machine that can do the following three-step operation.
- Select two indices i<ji<j such that the dust levels aiai, ai+1ai+1, ……, aj−1aj−1 are all strictly greater than 00.
- Set aiai to ai−1ai−1.
- Set ajaj to aj+1aj+1.
Mark's goal is to make a1=a2=…=an−1=0a1=a2=…=an−1=0 so that he can nicely sweep the nn-th room. Determine the minimum number of operations needed to reach his goal.
Input
The first line contains a single integer tt (1≤t≤1041≤t≤104) — the number of test cases.
The first line of each test case contains a single integer nn (2≤n≤2⋅1052≤n≤2⋅105) — the number of rooms.
The second line of each test case contains nn integers a1a1, a2a2, ..., anan (0≤ai≤1090≤ai≤109) — the dust level of each room.
It is guaranteed that the sum of nn across all test cases does not exceed 2⋅1052⋅105.
Output
For each test case, print a line containing a single integer — the minimum number of operations. It can be proven that there is a sequence of operations that meets the goal.
Example
input
Copy
4 3 2 0 0 5 0 2 0 2 0 6 2 0 3 0 4 6 4 0 0 0 10output
Copy
3 5 11 0
题意:给你一个数组,每次可以进行一次操作,这次操作要选择一个i和一个j,而且要求从a[i]到a[j-1]必须大于0,然后a[i]-1,a[j]+1,询问这样操作需要进行多少次才能将这个数组出了第n个数之外全都变成0;
思路:我们需要先把从第一个不是0的数到第n个数之间为零的数全都变成非零数,这样才能让从i到n所有的数都大于0,从而可以进行操作,那么这些为零的数就必须从前面不为零的数进行操作,而让0变成非零只需要让它加一即可,所以我们最后会发现,最小操作次数就是从第一个不为零的数到a[n],里面o的个数加上a[1]到a[n-1]的前缀和。
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
int main()
{
ll sum,a[200010],i,n,t,f;
scanf("%lld",&t);
while(t--)
{
scanf("%lld",&n);
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
f=0;//标记第一个不为零的数是否出现,若出现了就开始记录0的个数
sum=0;
for(i=1;i<n;i++)
{
if(a[i]!=0&&f==0)
{
f=1;
}
if(a[i]!=0)
sum=sum+a[i];
if(a[i]==0&&f==1)
{
sum++;//等于0就让答案加一
}
}
printf("%lld\n",sum);
}
return 0;
}
C. Mark and His Unfinished Essay
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
One night, Mark realized that there is an essay due tomorrow. He hasn't written anything yet, so Mark decided to randomly copy-paste substrings from the prompt to make the essay.
More formally, the prompt is a string ss of initial length nn. Mark will perform the copy-pasting operation cc times. Each operation is described by two integers ll and rr, which means that Mark will append letters slsl+1…srslsl+1…sr to the end of string ss. Note that the length of ss increases after this operation.
Of course, Mark needs to be able to see what has been written. After copying, Mark will ask qq queries: given an integer kk, determine the kk-th letter of the final string ss.
Input
The first line contains a single integer tt (1≤t≤10001≤t≤1000) — the number of test cases.
The first line of each test case contains three integers nn, cc, and qq (1≤n≤2⋅1051≤n≤2⋅105, 1≤c≤401≤c≤40, and 1≤q≤1041≤q≤104) — the length of the initial string ss, the number of copy-pasting operations, and the number of queries, respectively.
The second line of each test case contains a single string ss of length nn. It is guaranteed that ss only contains lowercase English letters.
The following cc lines describe the copy-pasting operation. Each line contains two integers ll and rr (1≤l≤r≤10181≤l≤r≤1018). It is also guaranteed that rr does not exceed the current length of ss.
The last qq lines of each test case describe the queries. Each line contains a single integer kk (1≤k≤10181≤k≤1018). It is also guaranteed that kk does not exceed the final length of ss.
It is guaranteed that the sum of nn and qq across all test cases does not exceed 2⋅1052⋅105 and 104104, respectively.
Output
For each query, print the kk-th letter of the final string ss.
题意:给你一个初始字符串,c次操作,每次指定一个区间l,r,将字符串从l到r的部分复制粘贴的字符串的末尾,q次询问,问你第k个字符是啥。
思路:因为k的范围太大了,到了10e19,所以遍历什么的之类想都别想了,此时我们可以看到,操作c的范围很小,只有40,我们可以从这下手,因为每次复制粘贴得到的字符都是从之前的字符串得来的,所以我们可以从后向前推,从询问的第k个字符出发,逆着推,直到k在初始字符串的范围,输出就行。
#include <bits/stdc++.h>
using namespace std;
struct node
{
long long int ll,rr,st,ed;//ll,rr指的是这段字符串是从第ll到第rr的字符串复制的
//st,ed指的是这段字符串是位于所有字符串的st到ed这个区间的
}a[200010];
int main()
{
char s[200010];
long long int t,n,c,q,k;
scanf("%lld",&t);
while(t--)
{
scanf("%lld %lld %lld",&n,&c,&q);
getchar();
scanf("%s",s+1);
k=n+1;
for(int i=1; i<=c; i++)
{
scanf("%lld %lld",&a[i].ll,&a[i].rr);
a[i].st=k;
a[i].ed=k+a[i].rr-a[i].ll;
k=a[i].ed+1;
//printf("%lld %lld\n",a[i].st,a[i].ed);
}
while(q--)
{
scanf("%lld",&k);
if(k>=1&&k<=n)
{
printf("%c\n",s[k]);
continue;
}
for(int i=1; i<=c; i++)
{
if(k>=a[i].st&&k<=a[i].ed)
{
while(n==n)
{
k=a[i].ll+k-a[i].st;//关键公式,推出k是从哪个数组下标复制来的
if(k>=1&&k<=n)
{
printf("%c\n",s[k]);
break;
}
else
{
while(i--)
{
if(k>=a[i].st&&k<=a[i].ed)
break;
}
}
}
}
}
}
}
}