First-rate specialists graduate from Berland State Institute of Peace and Friendship. You are one of the most talented students in this university. The education is not easy because you need to have fundamental knowledge in different areas, which sometimes are not related to each other.
For example, you should know linguistics very well. You learn a structure of Reberland language as foreign language. In this language words are constructed according to the following rules. First you need to choose the "root" of the word — some string which has more than 4 letters. Then several strings with the length 2 or 3 symbols are appended to this word. The only restriction — it is not allowed to append the same string twice in a row. All these strings are considered to be suffixes of the word (this time we use word "suffix" to describe a morpheme but not the few last characters of the string as you may used to).
Here is one exercise that you have found in your task list. You are given the word s. Find all distinct strings with the length 2 or 3, which can be suffixes of this word according to the word constructing rules in Reberland language.
Two strings are considered distinct if they have different length or there is a position in which corresponding characters do not match.
Let's look at the example: the word abacabaca is given. This word can be obtained in the following ways: , where the root of the word is overlined, and suffixes are marked by "corners". Thus, the set of possible suffixes for this word is {aca, ba, ca}.
The only line contains a string s (5 ≤ |s| ≤ 104) consisting of lowercase English letters.
On the first line print integer k — a number of distinct possible suffixes. On the next k lines print suffixes.
Print suffixes in lexicographical (alphabetical) order.
abacabaca
3 aca ba ca
abaca
0
The first test was analysed in the problem statement.
In the second example the length of the string equals 5. The length of the root equals 5, so no string can be used as a suffix.
简单DP。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=10005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
string a[maxn*2];
string s;
bool dp[maxn][2];
int main() {
cin >> s;
int i,len=s.length(),m=0;
mem0(dp);
for (i=len-2;i>=5;i--) {
if (len-i==2) {
a[++m]=s.substr(i,2);
dp[i][0]=1;
} else if (len-i==3) {
a[++m]=s.substr(i,3);
dp[i][1]=1;
} else if (len-i==4) {
if (s.substr(i,2)!=s.substr(i+2,2)) {
a[++m]=s.substr(i,2);
dp[i][0]=1;
}
} else {
if ((s.substr(i,2)!=s.substr(i+2,2)&&dp[i+2][0])||dp[i+2][1]) {
a[++m]=s.substr(i,2);
dp[i][0]=1;
}
if ((s.substr(i,3)!=s.substr(i+3,3)&&dp[i+3][1])||dp[i+3][0]) {
a[++m]=s.substr(i,3);
dp[i][1]=1;
}
}
// cout << dp[i][0] << ' ' << dp[i][1] << endl;
}
sort(a+1,a+m+1);
int ans=unique(a+1,a+m+1)-a-1;
printf("%d\n",ans);
for (i=1;i<=ans;i++) {
cout << a[i] << endl;
}
return 0;
}
C. Codeword 题解
Group of Berland scientists, with whom you have a close business relationship, makes a research in the area of peaceful nuclear energy. In particular, they found that a group of four nanobots, placed on a surface of a plate, can run a powerful chain reaction under certain conditions.
To be precise, researchers introduced a rectangular Cartesian coordinate system on a flat plate and selected four distinct points with integer coordinates where bots will be placed initially. Next each bot will be assigned with one of the four directions (up, down, left or right) parallel to the coordinate axes. After that, each bot is shifted by an integer distance (which may be different for different bots) along its direction. The chain reaction starts, if the bots are in the corners of a square with positive area with sides parallel to the coordinate axes. Each corner of the square must contain one nanobot. This reaction will be stronger, if bots spend less time to move. We can assume that bots move with unit speed. In other words, the lesser is the maximum length traveled by bot, the stronger is reaction.
Scientists have prepared a set of plates and selected starting position for the bots for each plate. Now they ask you to assign the direction for each bot to move after landing such that the maximum length traveled by bot is as small as possible.
The first line contains an integer number t (1 ≤ t ≤ 50) — the number of plates.
t descriptions of plates follow. A description of each plate consists of four lines. Each line consists of a pair of integers numbers xi, yi ( - 108 ≤ xi, yi ≤ 108) — coordinates of the next bot. All bots are in different locations.
Note, though, the problem can include several records in one test, you can hack other people's submissions only with the test of one plate, i.e. parameter t in a hack test should be equal to 1.
Print answers for all plates separately. First goes a single integer number in a separate line. If scientists have made an unfortunate mistake and nanobots are not able to form the desired square, print -1. Otherwise, print the minimum possible length of the longest bot's path.
If a solution exists, in the next four lines print two integer numbers — positions of each bot after moving. Print bots' positions in the order they are specified in the input data.
If there are multiple solution, you can print any of them.
2 1 1 1 -1 -1 1 -1 -1 1 1 2 2 4 4 6 6
0 1 1 1 -1 -1 1 -1 -1 -1
在四个坐标上放了四个机器人。现在让他们朝四个方向当中的一个走任意步,使得最后四个机器人形成一个正方形。
问移动最多的机器人最少移动多少步。
先枚举正方形的边长,肯定是|xi-xj|或是|yi-yj|,因为总是有两个点移动的方向平行。
接着枚举正方形左上角坐标。当有两个点移动的方向垂直时,当纵坐标不变,横坐标是x,x-d或x+d。当所有点移动的方向平行时,可以看做这些点在一个轴上移动,此时要使移动最多的点移动步数最少,贪心的做法是将它们移到相差最大的两个点的中点上。
当边长,坐标都得到时,枚举4的全排列确定每个坐标对应的点。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=4,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int x[maxn],y[maxn],ax[maxn],ay[maxn];
int solve() {
int ans=2*inf;
int i,j;
for (auto y1:y) {
for (auto y2:y) {
if (y1==y2) continue;
int d=abs(y1-y2); //枚举矩形边长
set<int> st;
//枚举左上角
for (auto x1:x)
for (auto x2:x)
for (auto r: {0,-d,-2*d,1,-d+1,-2*d+1})
st.insert((x1+x2+r)/2);
for (auto x1:st) {
int p[4]={3,2,1,0};
for (j=0;j<24;j++) {
next_permutation(p,p+4);
int nx[4]={x1,x1,x1+d,x1+d};
int ny[4]={y1,y2,y1,y2};
for (i=0;i<4;i++)
if (nx[i]!=x[p[i]]&&ny[i]!=y[p[i]]) break;
if (i!=4) continue;
int u=0;
for (i=0;i<4;i++)
u=max(u,abs(nx[i]-x[p[i]])+abs(ny[i]-y[p[i]]));
if (u<ans) {
ans=u;
for (i=0;i<4;i++)
ax[p[i]]=nx[i],ay[p[i]]=ny[i];
}
}
}
}
}
return ans;
}
int main() {
int cas;
scanf("%d",&cas);
while (cas--) {
int i,ans;
for (i=0;i<4;i++) {
scanf("%d %d",&x[i],&y[i]);
x[i]+=1e9;y[i]+=1e9;
}
int z1,z2;
z1=solve();
swap(x,y);swap(ax,ay);
z2=solve();
swap(x,y);swap(ax,ay);
if (z1==z2&&z2==2*inf) {
printf("-1\n");
} else {
if (z1<z2) ans=solve(); else ans=z2;
printf("%d\n", ans);
for (i=0;i<4;i++) ax[i]-=1e9,ay[i]-=1e9;
for (i=0;i<4;i++) printf("%d %d\n",ax[i],ay[i]);
}
}
return 0;
}
SAM+线段树合并
待补