A2. Gardener and the Capybaras (hard version)
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
This is an hard version of the problem. The difference between the versions is that the string can be longer than in the easy version. You can only do hacks if both versions of the problem are passed.
Kazimir Kazimirovich is a Martian gardener. He has a huge orchard of binary balanced apple trees.
Recently Casimir decided to get himself three capybaras. The gardener even came up with their names and wrote them down on a piece of paper. The name of each capybara is a non-empty line consisting of letters "a" and "b".
Denote the names of the capybaras by the lines aa, bb, and cc. Then Casimir wrote the nonempty lines aa, bb, and cc in a row without spaces. For example, if the capybara's name was "aba", "ab", and "bb", then the string the gardener wrote down would look like "abaabbb".
The gardener remembered an interesting property: either the string bb is lexicographically not smaller than the strings aa and cc at the same time, or the string bb is lexicographically not greater than the strings aa and cc at the same time. In other words, either a≤ba≤b and c≤bc≤b are satisfied, or b≤ab≤a and b≤cb≤c are satisfied (or possibly both conditions simultaneously). Here ≤≤ denotes the lexicographic "less than or equal to" for strings. Thus, a≤ba≤b means that the strings must either be equal, or the string aa must stand earlier in the dictionary than the string bb. For a more detailed explanation of this operation, see "Notes" section.
Today the gardener looked at his notes and realized that he cannot recover the names because they are written without spaces. He is no longer sure if he can recover the original strings aa, bb, and cc, so he wants to find any triplet of names that satisfy the above property.

Input
Each test contains multiple test cases. The first line contains the number of test cases tt (1≤t≤1041≤t≤104). The description of the test cases follows.
The only line of a test case contains the string ss (3≤|s|≤2⋅1053≤|s|≤2⋅105) — the names of the capybaras, written together. The string consists of English letters 'a' and 'b' only.
It is guaranteed that the sum of string lengths over all test cases does not exceed 4⋅1054⋅105.
Output
For each test case, print three strings aa, bb and cc on a single line, separated by spaces — names of capybaras, such that writing them without spaces results in a line ss. Either a≤ba≤b and c≤bc≤b, or b≤ab≤a and b≤cb≤c must be satisfied.
If there are several ways to restore the names, print any of them. If the names cannot be recovered, print ":(" (without quotes).
Example
input
Copy
5bbbaabaaaaabbaabbb
output
Copy
b bb a
a b a
a a a
ab b a
a bb b
Note
A string xx is lexicographically smaller than a string yy if and only if one of the following holds:
xx is a prefix of yy, but x≠yx≠y;
in the first position where xx and yy differ, the string xx has the letter 'a', and the string yy has the letter 'b'.
Now let's move on to the examples.
In the first test case, one of the possible ways to split the line ss into three lines —is "b", "bb", "a".
In the third test case, we can see that the split satisfies two conditions at once (i.e., a≤ba≤b, c≤bc≤b, b≤ab≤a and b≤cb≤c are true simultaneously).
#include<bits/stdc++.h>
using namespace std;
int t,l;
string s;
int main()
{
cin>>t;
while(t--)
{
cin>>s;
l=s.size();
if(s[0]=='a'&&s[1]=='b')
{
cout<<"a "<<s.substr(1,l-2)<<" "<<s[l-1];
}
else
cout<<s[0]<<" "<<s[1]<<" "<<s.substr(2,l);
cout<<endl;
}
return 0;
}
Prove Him Wrong
Recently, your friend discovered one special operation on an integer array �a :
Choose two indices �i and �j ( �≠�i=j );
Set ��=��=∣��−��∣ai=aj=∣ai−aj∣ .
After playing with this operation for a while, he came to the next conclusion:
For every array �a of �n integers, where 1≤��≤1091≤ai≤109 , you can find a pair of indices (�,�)(i,j) such that the total sum of �a will decrease after performing the operation.
This statement sounds fishy to you, so you want to find a counterexample for a given integer �n . Can you find such counterexample and prove him wrong?
In other words, find an array �a consisting of �n integers �1,�2,…,��a1,a2,…,an ( 1≤��≤1091≤ai≤109 ) such that for all pairs of indices (�,�)(i,j) performing the operation won't decrease the total sum (it will increase or not change the sum).
输入格式
The first line contains a single integer �t ( 1≤�≤1001≤t≤100 ) — the number of test cases. Then �t test cases follow.
The first and only line of each test case contains a single integer �n ( 2≤�≤10002≤n≤1000 ) — the length of array �a .
输出格式
For each test case, if there is no counterexample array �a of size �n , print NO.
Otherwise, print YES followed by the array �a itself ( 1≤��≤1091≤ai≤109 ). If there are multiple counterexamples, print any.
题意翻译
你需要在一个整数序列 �a 上执行一个操作:
选择两个位置 �,� (�≠�)i,j(i=j);
使 ��=��=∣��−��∣ai=aj=∣ai−aj∣。
接着有一个猜想:
对于每一个有 �n 个整数的序列 �a,满足 ��≤109ai≤109,在执行一个操作后,这个序列的数字总和一定会变小。
现在给你一个整数 �n,你需要构造一个长度为 �n 的序列,使得它不满足上面的这个猜想。
输入输出样例
输入 #1复制
3
2
512
3
输出 #1复制
YES
1 337
NO
YES
31 4 159
说明/提示
In the first test case, the only possible pairs of indices are (1,2)(1,2) and (2,1)(2,1) .
If you perform the operation on indices (1,2)(1,2) (or (2,1)(2,1) ), you'll get �1=�2=∣1−337∣=336a1=a2=∣1−337∣=336 , or array [336,336][336,336] . In both cases, the total sum increases, so this array �a is a counterexample.
简单的构造
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a[1111],t,n;
int main()
{
a[0]=1;
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<n;i++)
{
a[i]=a[i-1]*3;
if(a[i]>1e9)
{
cout<<"NO"<<endl;
goto tag;
}
}
cout<<"YES"<<endl;
for(int i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
tag:;
}
return 0;
}
P2360 地下城主
题目描述
你参加了一项秘密任务,在任务过程中你被困在了一个3D的地下监狱里面,任务是计时的,你现在需要在最短的时间里面从地牢里面逃出来继续你的任务。地牢由若干层组成,每一层的形状都是长宽一样的矩形,地牢被分成了若干小格,当小格没有被岩石所占据时,你可以前往所在小格的前方,后方,左方,右方,上层,下层的小格。每走一小格花费一分钟时间。
你能不能顺利的从地牢里面逃出来呢?如果可以,那所需要的最短时间又是多少呢?
//据说出口藏有神器。
输入格式
第一行输入L R C(L为地牢的层数,R为每层小格的行数,C为每层小格的列数,其中1<=L,R,C<=30)。
第二行开始输入L层地牢的格局,每一层有R行,每行有C个小格,两层地牢中间有空行隔开。
输入的文件中,“S”代表你的起始点,“E”代表你所要到达的出口,“#”为小格被岩石占据,“.”表示没有被岩石占据。
输出格式
输出包含一行,当你可以顺利到达出口时请输出:
“Escaped in x minute(s).”,x代表你所花费的最短时间;
否则请输出:“Trapped!”。
输入输出样例
输入 #1复制
3 4 5
S....
.###.
.##..
###.#
#####
#####
##.##
##...
#####
#####
#.###
####E
输出 #1复制
Escaped in 11 minute(s).
说明/提示
来源:POJ 2251
简单的广搜,只是从一般的二维改成了三维
#include<bits/stdc++.h>
using namespace std;
struct node
{
int x,y,z,t,v;
char ch;
} ;
int px[]={0,0,0,0,1,-1};
int py[]={1,-1,0,0,0,0};
int pz[]={0,0,1,-1,0,0};
queue<node> q;
node a[55][55][55];
int l,r,c,px1,px2,py1,py2,pz1,pz2;
int main()
{
cin>>l>>r>>c;
for(int i=1;i<=l;i++)
{
for(int j=1;j<=r;j++)
{
for(int k=1;k<=c;k++)
{
cin>>a[i][j][k].ch;
a[i][j][k].x=i;
a[i][j][k].y=j;
a[i][j][k].z=k;
if(a[i][j][k].ch=='S')
{
px1=i;
py1=j;
pz1=k;
}
if(a[i][j][k].ch=='E')
{
px2=i;
py2=j;
pz2=k;
}
}
}
}
a[px1][py1][pz1].v=1;
q.push(a[px1][py1][pz1]);
while(!q.empty())
{
node tmp=q.front();
q.pop();
for(int i=0;i<6;i++)
{
int nx=tmp.x+px[i];
int ny=tmp.y+py[i];
int nz=tmp.z+pz[i];
if(nx==px2&&ny==py2&&nz==pz2)
{
cout<<"Escaped in "<<tmp.t+1<<" minute(s).";
return 0;
}
if(nx<=l&&nx>=1&&ny<=r&&ny>=1&&nz>=1&&nz<=c&&!a[nx][ny][nz].v&&a[nx][ny][nz].ch!='#')
{
a[nx][ny][nz].v=1;
a[nx][ny][nz].t=tmp.t+1;
q.push(a[nx][ny][nz]);
}
}
}
cout<<"Trapped!";
return 0;
}
题目描述
一个�×�N×M的由非负整数构成的数字矩阵,你需要在其中取出若干个数字,使得取出的任意两个数字不相邻(若一个数字在另外一个数字相邻88个格子中的一个即认为这两个数字相邻),求取出数字和最大是多少。
输入格式
第1行有一个正整数�T,表示了有�T组数据。
对于每一组数据,第一行有两个正整数�N和�M,表示了数字矩阵为�N行�M列。
接下来�N行,每行�M个非负整数,描述了这个数字矩阵。
输出格式
�T行,每行一个非负整数,输出所求得的答案。
输入输出样例
输入 #1复制
3
4 4
67 75 63 10
29 29 92 14
21 68 71 56
8 67 91 25
2 3
87 70 85
10 3 17
3 3
1 1 1
1 99 1
1 1 1
输出 #1复制
271
172
99
说明/提示
对于第1组数据,取数方式如下:
[67] 75 63 10
29 29 [92] 14
[21] 68 71 56
8 67 [91] 25
对于20%20%的数据,�,�≤3N,M≤3;
对于40%40%的数据,�,�≤4N,M≤4;
对于60%60%的数据,�,�≤5N,M≤5;
对于100%100%的数据,�,�≤6,�≤20N,M≤6,T≤20。
#include<bits/stdc++.h>
using namespace std;
void dfs(int x,int y,int sum);
bool ck(int x,int y);
int t,a[11][11],v[11][11];
int px[]={0,1,1,1,0,-1,-1,-1};
int py[]={1,1,0,-1,-1,-1,0,1};
int n,m,ans=0;
int main()
{
cin>>t;
while(t--)
{
cin>>n>>m;
ans=0;
memset(v,0,sizeof(v));
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
dfs(1,0,0);
cout<<ans<<endl;
}
return 0;
}
void dfs(int x,int y,int sum)
{
if(x>n)
{
ans=max(ans,sum);
return ;
}
int ny=y+1,nx=x;
if(ny>m)
{
ny=1;
nx=x+1;
}
if(ck(x,y))
{
v[x][y]=1;
dfs(nx,ny,sum+a[x][y]);
v[x][y]=0;
}
dfs(nx,ny,sum);
}
bool ck(int x,int y)
{
if(x>n||y>m||x<1||y<1)
return 0;
for(int i=0;i<8;i++)
{
if(v[x+px[i]][y+py[i]])
return 0;
}
return 1;
}
P8661 [蓝桥杯 2018 省 B] 日志统计
题目描述
小明维护着一个程序员论坛。现在他收集了一份“点赞”日志,日志共有 �N 行。其中每一行的格式是 ts id,表示在 ��ts 时刻编号 ��id 的帖子收到一个“赞”。
现在小明想统计有哪些帖子曾经是“热帖”。如果一个帖子曾在任意一个长度为 �D 的时间段内收到不少于 �K 个赞,小明就认为这个帖子曾是“热帖”。
具体来说,如果存在某个时刻 �T 满足该帖在 [�,�+�)[T,T+D) 这段时间内(注意是左闭右开区间)收到不少于 �K 个赞,该帖就曾是“热帖”。
给定日志,请你帮助小明统计出所有曾是“热帖”的帖子编号。
输入格式
第一行包含三个整数 �N、�D 和 �K。
以下 �N 行每行一条日志,包含两个整数 ��ts 和 ��id。
输出格式
按从小到大的顺序输出热帖 ��id。每个 ��id 一行。
输入输出样例
输入 #1复制
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3
输出 #1复制
1
3
说明/提示
对于 50%50% 的数据,1≤�≤�≤10001≤K≤N≤1000。
对于 100%100% 的数据,1≤�≤�≤1051≤K≤N≤105,0≤��,��≤1050≤id,ts≤105。
时限 1 秒, 256M。蓝桥杯 2018 年第九届省赛
简单的双指针,对于每个人,一前一后,差值在k以内时前面一直移动,大于k时后面前移直至符合题意
#include<bits/stdc++.h>
using namespace std;
bool cmp(pair<int,int> a,pair<int,int> b);
int n,d,k;
queue<int> q;
pair<int,int> p[111111];
int main()
{
cin>>n>>d>>k;
for(int i=1;i<=n;i++)
{
cin>>p[i].first>>p[i].second;
}
sort(p+1,p+1+n,cmp);
for(int i=1;i<=n;i++)
{
int j=i;
while(p[i].second==p[j].second&&p[j].first<p[i].first+d)
j++;
if(j-i>=k)
{
q.push(p[i].second);
i=j-1;
}
}
while(!q.empty())
{
cout<<q.front()<<endl;
q.pop();
}
return 0;
}
bool cmp(pair<int,int> a,pair<int,int> b)
{
if(a.second!=b.second)
return a.second<b.second;
return a.first<b.first;
}
P1123 取数游戏
题目描述
一个�×�N×M的由非负整数构成的数字矩阵,你需要在其中取出若干个数字,使得取出的任意两个数字不相邻(若一个数字在另外一个数字相邻88个格子中的一个即认为这两个数字相邻),求取出数字和最大是多少。
输入格式
第1行有一个正整数�T,表示了有�T组数据。
对于每一组数据,第一行有两个正整数�N和�M,表示了数字矩阵为�N行�M列。
接下来�N行,每行�M个非负整数,描述了这个数字矩阵。
输出格式
�T行,每行一个非负整数,输出所求得的答案。
输入输出样例
输入 #1复制
3
4 4
67 75 63 10
29 29 92 14
21 68 71 56
8 67 91 25
2 3
87 70 85
10 3 17
3 3
1 1 1
1 99 1
1 1 1
输出 #1复制
271
172
99
说明/提示
对于第1组数据,取数方式如下:
[67] 75 63 10
29 29 [92] 14
[21] 68 71 56
8 67 [91] 25
对于20%20%的数据,�,�≤3N,M≤3;
对于40%40%的数据,�,�≤4N,M≤4;
对于60%60%的数据,�,�≤5N,M≤5;
对于100%100%的数据,�,�≤6,�≤20N,M≤6,T≤20。
dfs,但是是按照行一行一行搜,
#include<bits/stdc++.h>
using namespace std;
void dfs(int x,int y,int sum);
bool ck(int x,int y);
int t,a[11][11],v[11][11];
int px[]={0,1,1,1,0,-1,-1,-1};
int py[]={1,1,0,-1,-1,-1,0,1};
int n,m,ans=0;
int main()
{
cin>>t;
while(t--)
{
cin>>n>>m;
ans=0;
memset(v,0,sizeof(v));
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
dfs(1,0,0);
cout<<ans<<endl;
}
return 0;
}
void dfs(int x,int y,int sum)
{
if(x>n)
{
ans=max(ans,sum);
return ;
}
int ny=y+1,nx=x;
if(ny>m)
{
ny=1;
nx=x+1;
}
if(ck(x,y))
{
v[x][y]=1;
dfs(nx,ny,sum+a[x][y]);
v[x][y]=0;
}
dfs(nx,ny,sum);
}
bool ck(int x,int y)
{
if(x>n||y>m||x<1||y<1)
return 0;
for(int i=0;i<8;i++)
{
if(v[x+px[i]][y+py[i]])
return 0;
}
return 1;
}