AGTC

Description
Let x and y be two strings over some finite alphabet A. We would like to transform x into y allowing only operations given below:

Certainly, we would like to minimize the number of all possible operations.
Illustration

A G T A A G T /* A G G C | | | | | | | A G T /* C /* T G A C G C

Deletion: /* in the bottom line
Insertion: /* in the top line
Change: when the letters at the top and bottom are distinct

This tells us that to transform x = AGTCTGACGC into y = AGTAAGTAGGC we would be required to perform 5 operations (2 changes, 2 deletions and 1 insertion). If we want to minimize the number operations, we should do it like

A G T A A G T A G G C | | | | | | | A G T C T G /* A C G C

and 4 moves would be required (3 changes and 1 deletion).

In this problem we would always consider strings x and y to be fixed, such that the number of letters in x is m and the number of letters in y is n where nm.

Assign 1 as the cost of an operation performed. Otherwise, assign 0 if there is no operation performed.

Write a program that would minimize the number of possible operations to transform any string x into a string y.

Input

The input consists of the strings x and y prefixed by their respective lengths, which are within 1000.

Output

An integer representing the minimum number of possible operations to transform any string x into a string y.

Sample Input

10 AGTCTGACGC 11 AGTAAGTAGGC

Sample Output

4

题意 给你两个DNA序列 求第一个第一个序列至少经过多次删除 、替换 或添加碱基得到第二个序列 其实分析一下可以发现 只要求出两个序列的最长公共子序列 这部分就可以不动了 然后较长序列的长度减去最长公共子序列的长度就是答案了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1005;
int la, lb, d[N][N];
char a[N], b[N];

void lcs()
{
memset (d, 0, sizeof (d));
for (int i = 1; i <= la; ++i)
for (int j = 1; j <= lb; ++j)
if (a[i] == b[j]) d[i][j] = d[i - 1][j - 1] + 1;
else d[i][j] = max (d[i - 1][j], d[i][j - 1]);
}

int main()
{
while (~scanf ("%d%s%d%s", &la, a + 1, &lb, b + 1))
{
lcs();
printf ("%d\n", max (la, lb) - d[la][lb]);
}
return 0;
}

Queue

Description
Linda is a teacher in ACM kindergarten. She is in charge of n kids. Because the dinning hall is a little bit far away from the classroom, those n kids have to walk in line to the dinning hall every day. When they are walking in line, if and only if two kids can see each other, they will talk to each other. Two kids can see each other if and only if all kids between them are shorter then both of them, or there are no kids between them. Kids do not only look forward, they may look back and talk to kids behind them. Linda don’t want them to talk too much (for it’s not safe), but she also don’t want them to be too quiet(for it’s boring), so Linda decides that she must form a line in which there are exactly m pairs of kids who can see each other. Linda wants to know, in how many different ways can she form such a line. Can you help her?
Note: All kids are different in height.

Input

Input consists of multiple test cases. Each test case is one line containing two integers. The first integer is n, and the second one is m. (0 < n <= 80, 0 <= m <= 10000).
Input ends by a line containing two zeros.

Output

For each test case, output one line containing the reminder of the number of ways divided by 9937.

Sample Input

1 0 2 0 3 2 0 0

Sample Output

1 0 4

题意 linda在一个幼儿园当老师 他要把n个学生排成一列 使只有m对学生能够讲话 当两个学生相邻或者他们之间的所有人都比他们矮时 他们就能够讲话

每个学生的身高都不同

令d[i][j]表示把i个学生排成一列使j对学生能够讲话的方法数

可以把i个学生分成i-1个学生和一个最矮的学生 把这个学生放在i-1个学生中任意两个学生之间都不会影响原来的结果 但是能讲话的学生对数增加了2 有i-2种放法

或者把这个最矮的学生放在两边 这样能讲话的对数只增加了1 有两种放法

所以有转移方程d[i][j]=d[i-1][j-2]/*i-2+d[i-1][j-1]/*2(j>=2)

j<2时只有d[1][0]=1(学生数大于1就有相邻的就能讲话了) 和d[2][1]=2(学生数大于2肯定不止一对能讲话了)两个有值 可以作为初始条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 81, M = 10001;
int d[N][M], n, m;
int main()
{
d[1][0] = 1, d[2][1] = 2;
for (int i = 1; i < N; ++i)
for (int j = 2; j < M; ++j)
d[i][j] = (d[i - 1][j - 2] * (i - 2) + 2 * d[i - 1][j - 1]) % 9937;

while (scanf ("%d%d", &n, &m), n)
printf ("%d\n", d[n][m]);

return 0;
}

Not So Flat After All

Description
Any positive integer v can be written as p1a1/p2a2/…/*pnan where pi is a prime number and ai ≥ 0. For example: 24 = 23/*31.
Pick any two prime numbers p1 and p2 where p1 = p2. Imagine a two dimensional plane where the powers of p1 are plotted on the x-axis and the powers of p2 on the y-axis. Now any number that can be written as p1a1/*p2a2 can be plotted on this plane at location (x, y) = (a1, a2). The figure on the right shows few examples where p1 = 3 and p2 = 2.
This idea can be extended for any N-Dimensional space where each of the N axes is assigned a unique prime number. Each N-Dimensional space has a unique set of primes.
We call such set the Space Identification Set or S for short. |S| (the ordinal of S) is N.
Any number that can be expressed as a multiplication of pi ∈ S (each raised to a power (ai ≥ 0) can be plotted in this |S|-Dimensional space. The figure at the bottom illustrates this idea for N = 3 and S = {2, 3, 7}. Needless to say, any number that can be plotted on space A can also be plotted on space B as long as SA \subset SB.
We define the distance between any two points in a given N-Dimensional space to be the sum of units traveled to get from one point to the other while following the grid lines (i.e. movement is always parallel to one of the axes.) For example, in the figure below, the distance between 168 and 882 is 4.
Given two positive integers, write a program that determines the minimum ordinal of a space where both numbers can be plotted in. The program also determines the distance between these two integers in that space.

Input

Your program will be tested on one or more test cases. Each test case is specified on a line with two positive integers (0 < A,B < 1, 000, 000) where A /* B > 1.
The last line is made of two zeros.

Output

For each test case, print the following line:
k. X:D
Where k is the test case number (starting at one,) X is the minimum ordinal needed in a space that both A and B can be plotted in. D is the distance between these two points.

Sample Input

168 882 770 792 0 0

Sample Output

  1. 3:4 2. 5:6

题意 给你两个数a,b 求a,b所有的质因数个数 和每个质因数个数的差的绝对值的和 被描述得好复杂 理解了就是个水题;

素数问题就先打个素数表吧 然后能被整除的就是质因数了 然后统计a,b分别能被这个数整除多少次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
const int N = 1000001;
int p[N], ans[N], vis[N], a, b;
void initPrime()
{
int num = 0, m = sqrt (N + 0.5);
for (int i = 2; i <= m; ++i)
if (vis[i] == 0)
for (int j = i * i; j <= N; j += i) vis[j] = 1;
for (int i = 2; i <= N; ++i)
if (vis[i] == 0) p[++num] = i;
}

int main()
{
initPrime();
int cas=0;
while (scanf ("%d%d", &a, &b),a)
{
int cnt = 0, ans = 0, ca, cb;
for (int i = 1; a > 1 || b > 1; ++i)
if (a % p[i] == 0 || b % p[i] == 0)
{
++cnt, ca = cb = 0;
while (a % p[i] == 0) a /= p[i], ++ca;
while (b % p[i] == 0) b /= p[i], ++cb;
ans += (ca > cb ? ca - cb : cb - ca);
}
printf ("%d. %d:%d\n", ++cas,cnt, ans);
}
return 0;
}

Blue Jeans

Description
The Genographic Project is a research partnership between IBM and The National Geographic Society that is analyzing DNA from hundreds of thousands of contributors to map how the Earth was populated.
As an IBM researcher, you have been tasked with writing a program that will find commonalities amongst given snippets of DNA that can be correlated with individual survey information to identify new genetic markers.
A DNA base sequence is noted by listing the nitrogen bases in the order in which they are found in the molecule. There are four bases: adenine (A), thymine (T), guanine (G), and cytosine (C). A 6-base DNA sequence could be represented as TAGACC.
Given a set of DNA base sequences, determine the longest series of bases that occurs in all of the sequences.

Input

Input to this problem will begin with a line containing a single integer n indicating the number of datasets. Each dataset consists of the following components:

Output

For each dataset in the input, output the longest base subsequence common to all of the given base sequences. If the longest common subsequence is less than three bases in length, display the string “no significant commonalities” instead. If multiple subsequences of the same longest length exist, output only the subsequence that comes first in alphabetical order.

Sample Input

3 2 GATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 3 GATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATA GATACTAGATACTAGATACTAGATACTAAAGGAAAGGGAAAAGGGGAAAAAGGGGGAAAA GATACCAGATACCAGATACCAGATACCAAAGGAAAGGGAAAAGGGGAAAAAGGGGGAAAA 3 CATCATCATCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC ACATCATCATAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AACATCATCATTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT

Sample Output

no significant commonalities AGATAC CATCATCAT

题意 给你n个DNA串 求它们的长度最大的公共子串 如果有多个 输出字典序最小的 长度小于3的不算

每个DNA串的长度都是60 可以从子串长度为60依次递减 并枚举所有该长度子串 当某个长度的子串也为其它n-1个串的子串时 就是我们要的答案了

判断是否为其它DNA串的子串直接kmp就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 15, M = 65, L = 60;

bool kmp (char s[], char p[])
{
int next[M];
next[0] = -1, next[1] = 0;
int plen = strlen (p), i = 0, j,slen = strlen (s);
while (++i < plen - 1)
{
j = next[i];
while (j != -1 && p[i] != p[j])
j = next[j];
next[i + 1] = j + 1;
}

i = j = 0;
while (i < slen && j < plen)
{
if (j == -1 || s[i] == p[j]) ++i, ++j;
else j = next[j];
}
return j == plen;
}

int main()
{
int cas, n, flag;
char s[N][M], tans[M],ans[M];
scanf ("%d", &cas);
while (cas--)
{
scanf ("%d", &n);
for (int i = flag = 0; i < n; ++i)
scanf ("%s", s[i]);
for (int lans = L; lans > 2 && flag == 0; --lans)
{
strcpy(ans,"ZZ");
for (int i = 0, j, k; i + lans <= L; ++i)
{
for (j = 0; j < lans; ++j)
tans[j] = s[0][i + j];
tans[j] = '\0';

for (k = 1; k < n; ++k)
if (!kmp (s[k], tans)) break;

if (k == n)
{
if(strcmp(ans,tans)>0) strcpy(ans,tans);
flag = 1;
}
}
}

if (flag == 1) printf ("%s\n", ans);
else printf ("no significant commonalities\n");
}
return 0;
}


A number of K balls are dropped one by one from the root of a fully binary tree structure FBT. Each time the ball being dropped first visits a non-terminal node. It then keeps moving down, either follows the path of the left subtree, or follows the path of the right subtree, until it stops at one of the leaf nodes of FBT. To determine a ball’s moving direction a flag is set up in every non-terminal node with two values, either false or true. Initially, all of the flags are false. When visiting a non-terminal node if the flag’s current value at this node isfalse, then the ball will first switch this flag’s value, i.e., from the false to the true, and then follow the left subtree of this node to keep moving down. Otherwise, it will also switch this flag’s value, i.e., from the true to the false, but will follow the right subtree of this node to keep moving down. Furthermore, all nodes of FBT are sequentially numbered, starting at 1 with nodes on depth 1, and then those on depth 2, and so on. Nodes on any depth are numbered from left to right.

For example, Fig. 1 represents a fully binary tree of maximum depth 4 with the node numbers 1, 2, 3, …, 15. Since all of the flags are initially set to be false, the first ball being dropped will switch flag’s values at node 1, node 2, and node 4 before it finally stops at position 8. The second ball being dropped will switch flag’s values at node 1, node 3, and node 6, and stop at position 12. Obviously, the third ball being dropped will switch flag’s values at node 1, node 2, and node 5 before it stops at position 10.

Fig. 1: An example of FBT with the maximum depth 4 and sequential node numbers.

Now consider a number of test cases where two values will be given for each test. The first value is D, the maximum depth of FBT, and the second one is I, the I**th ball being dropped. You may assume the value of I will not exceed the total number of leaf nodes for the given FBT.

Please write a program to determine the stop position P for each test case.

For each test cases the range of two parameters D and I is as below:

\begin{displaymath}2 \le D \le 20, \mbox{ and } 1 \le I \le 524288.\end{displaymath}

Contains l +2 lines. Line 1 I the number of test cases Line 2 test case /#1, two decimal numbers that are separatedby one blank … Line k+1 test case /#k Line l+1 test case /#l Line l+2 -1 a constant -1 representing the end of the input file

Contains l lines. Line 1 the stop position P for the test case /#1 … Line k the stop position P for the test case /#k … Line l the stop position P for the test case /#l

5 4 2 3 4 10 1 2 2 8 128 -1

12 7 512 3 255

题意 i个小球在一棵二叉树上下落 第奇数个到达某个节点就往左 否则往右 求最后一个小球下落到最底层所在结点的序号

对于第i个小球 在根结点处 若i是奇数 则它是往左的第(i+1)/2个小球 若i是偶数 则它是往右的第n/2个小球

而对于一个结点k 它的左子结点序号为2/*k 右子节点序号为2/*k+1 每次更新i到到最底层就得出结果了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<cstdio>
int main()
{
int cas, ans, d, i;
while (scanf ("%d", &cas), cas + 1)
{
while (cas--)
{
ans = 1;
scanf ("%d%d", &d, &i);
while (--d)
{
if (i % 2)
ans = ans * 2, i = (i + 1) / 2;
else
ans = ans * 2 + 1, i = i / 2;
}
printf ("%d\n", ans);
}
}
return 0;
}

题意 开始有n个盒子按1到n的顺序排列 对这些盒子进行m次操作 每次为把x移到y的左边 右边 交换x,y 颠倒顺序中的一个

求操作完成后所有奇数位原盒子序号的和;

直接模拟肯定会超时 用stl中的链表也超时 只能用数组自己模拟一个双向链表了 le[i],ri[i]分别表示第i个盒子左边盒子的序号和右边盒子的序号 代码中有注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 100005;
int le[N], ri[N], n, m;
typedef long long ll;

void link (int l, int r) //连接l和r,l在左边
{
le[r] = l; ri[l] = r;
}

int main()
{
int cas = 0, op, x, y, t;
while (scanf ("%d%d", &n, &m) != EOF)
{
for (int i = 1; i <= n; ++i)
ri[i] = i + 1, le[i] = i - 1;
ri[n] = 0, le[0] = n, ri[0] = 1;
int flag = 0; //判断是否翻转
while (m--)
{
scanf ("%d", &op);
if (op == 4) flag = !flag;
else
{
scanf ("%d%d", &x, &y);
if (flag && op != 3) op = 3 - op; //翻转后移动操作就相反了
if (ri[y] == x && op == 3) //方便后面判断交换是否相邻
t = x, x = y, y = t;
if ( (op == 1 && le[y] == x) || (op == 2 && ri[y] == x)) continue;

if (op == 1) //x移到y右边
link (le[x], ri[x]), link (le[y], x), link (x, y);
else if (op == 2) //x移到y左边
link (le[x], ri[x]), link (x, ri[y]), link (y, x);
else if (y == ri[x]) //op==3&&x,y相邻
link (le[x], y), link (x, ri[y]), link (y, x);
else //不相邻
{
int ry = ri[y], ly = le[y];
link (le[x], y), link (y, ri[x]), link (ly, x), link (x, ry);
}
}
}

t = 0; ll ans = 0;
for (int i = 1; i <= n; ++i)
{
t = ri[t];
if (i % 2) ans += t;
}
if (n % 2 == 0 && flag) //n为偶数且翻转过 故求的恰为偶数位的和
ans = (ll) n / 2 * (1 + n) - ans;
printf ("Case %d: %lld\n", ++cas, ans);
}
return 0;
}

Boxes in a Line

You have n boxes in a line on the table numbered 1 . . . n from left to right. Your task is to simulate 4
kinds of commands:
• 1 X Y : move box X to the left to Y (ignore this if X is already the left of Y )
• 2 X Y : move box X to the right to Y (ignore this if X is already the right of Y )
• 3 X Y : swap box X and Y
• 4: reverse the whole line.
Commands are guaranteed to be valid, i.e. X will be not equal to Y .
For example, if n = 6, after executing 1 1 4, the line becomes 2 3 1 4 5 6. Then after executing
2 3 5, the line becomes 2 1 4 5 3 6. Then after executing 3 1 6, the line becomes 2 6 4 5 3 1.
Then after executing 4, then line becomes 1 3 5 4 6 2

Input

There will be at most 10 test cases. Each test case begins with a line containing 2 integers n, m
(1 ≤ n, m ≤ 100, 000). Each of the following m lines contain a command.

Output

For each test case, print the sum of numbers at odd-indexed positions. Positions are numbered 1 to n
from left to right.

Sample Input

6 4
1 1 4
2 3 5
3 1 6
4
6 3
1 1 4
2 3 5
3 1 6
100000 1
4

Sample Output

Case 1: 12
Case 2: 9
Case 3: 2500050000

Max Sum

Problem Description

Given a sequence a[1],a[2],a[3]……a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.
Input

The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).
Output

For each test case, you should output two lines. The first line is “Case /#:”, /# means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.
Sample Input

2 5 6 -1 5 4 -7 7 0 6 -1 1 -6 7 -5
Sample Output

Case 1: 14 1 4 Case 2: 7 1 6

题意 求n个数字的最大连续和

DP的入门题目 令d[i]表示以第i个数a为右端的最大连续子序列和 那么很容易得出转移方程 d[i]=max(d[i-1]+a,a)

很显然 当第i个数比以第i-1个数为右端的最大和加上第i个数还大的时候 以第i个数为右端的最大和就是第i个数自己了 同时更新左端为自己

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 100005;
int main()
{
int a, cas, ans, l, le, ri, n, d[N];
scanf ("%d", &cas);
for (int k = 1; k <= cas; ++k)
{
memset (d, 0x8f, sizeof (d));
ans = d[0];
scanf ("%d", &n);
for (int i = 1; i <= n; ++i)
{
scanf ("%d", &a);
if (d[i - 1] + a < a)
d[i] = a, l = i;
else
d[i] = d[i - 1] + a;
if (d[i] > ans)
ans = d[i], le = l, ri = i;
}
if (k > 1) printf ("\n");
printf ("Case %d:\n%d %d %d\n", k, ans, le, ri);
}
return 0;
}

题意 所有可以表示为4/*k+1(k>=0)的数都称为“H数” 而在所有“H数”中只能被1和自身整除的H数称为“H素数“ 能表示成两个”H素数“积的数又称为”Semi-prime H数“

输入n 求1到n之间有多少个”Semi-prime H数“;

方法 先打个H素数表 再用H素数表中的数依次相乘 得到的数都标记 再用一个数组保存每个数以内的标记数 输入n后直接读数组就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1000001;
int vis[N],hp[N],ans[N],n;
int main()
{
int num=0,m=sqrt(N+0.5);
for(int i=5;i<=m;i+=4)
{
if(vis[i]==0)
for(int j=i*i;j<=N;j+=i)
vis[j]=1;
}
for(int i=5;i<N;i+=4)
if(!vis[i]) hp[++num]=i;

memset(vis,0,sizeof(vis));
for(int i=1;hp[i]*hp[i]<=N;++i)
for(int j=i;hp[i]*hp[j]<=N;++j)
++vis[hp[i]*hp[j]];
num=0;
for(int i=1;i<N;++i)
{
if(vis[i]>=1) ++num;
ans[i]=num;
}

while(scanf("%d",&n),n)
printf("%d %d\n",n,ans[n]);

return 0;
}

Semi-prime H-numbers

Description
This problem is based on an exercise of David Hilbert, who pedagogically suggested that one study the theory of 4n+1 numbers. Here, we do only a bit of that.

An H-number is a positive number which is one more than a multiple of four: 1, 5, 9, 13, 17, 21,… are the H-numbers. For this problem we pretend that these are the only numbers. The H-numbers are closed under multiplication.

As with regular integers, we partition the H-numbers into units, H-primes, and H-composites. 1 is the only unit. An H-number h is H-prime if it is not the unit, and is the product of two H-numbers in only one way: 1 × h. The rest of the numbers are H-composite.

For examples, the first few H-composites are: 5 × 5 = 25, 5 × 9 = 45, 5 × 13 = 65, 9 × 9 = 81, 5 × 17 = 85.

Your task is to count the number of H-semi-primes. An H-semi-prime is an H-number which is the product of exactly two H-primes. The two H-primes may be equal or different. In the example above, all five numbers are H-semi-primes. 125 = 5 × 5 × 5 is not an H-semi-prime, because it’s the product of three H-primes.

Input

Each line of input contains an H-number ≤ 1,000,001. The last line of input contains 0 and this line should not be processed.

Output

For each inputted H-number h, print a line stating h and the number of H-semi-primes between 1 and h inclusive, separated by one space in the format shown in the sample.

Sample Input

21 85 789 0

Sample Output

21 0 85 5 789 62

Semi-prime H-numbers

Description
This problem is based on an exercise of David Hilbert, who pedagogically suggested that one study the theory of 4n+1 numbers. Here, we do only a bit of that.

An H-number is a positive number which is one more than a multiple of four: 1, 5, 9, 13, 17, 21,… are the H-numbers. For this problem we pretend that these are the only numbers. The H-numbers are closed under multiplication.

As with regular integers, we partition the H-numbers into units, H-primes, and H-composites. 1 is the only unit. An H-number h is H-prime if it is not the unit, and is the product of two H-numbers in only one way: 1 × h. The rest of the numbers are H-composite.

For examples, the first few H-composites are: 5 × 5 = 25, 5 × 9 = 45, 5 × 13 = 65, 9 × 9 = 81, 5 × 17 = 85.

Your task is to count the number of H-semi-primes. An H-semi-prime is an H-number which is the product of exactly two H-primes. The two H-primes may be equal or different. In the example above, all five numbers are H-semi-primes. 125 = 5 × 5 × 5 is not an H-semi-prime, because it’s the product of three H-primes.

Input

Each line of input contains an H-number ≤ 1,000,001. The last line of input contains 0 and this line should not be processed.

Output

For each inputted H-number h, print a line stating h and the number of H-semi-primes between 1 and h inclusive, separated by one space in the format shown in the sample.

Sample Input

21 85 789 0

Sample Output

21 0 85 5 789 62

Broken Keyboard (a.k.a. Beiju Text)

You’re typing a long text with a broken keyboard. Well it’s not so badly broken. The only problem with the keyboard is that sometimes the “home” key or the “end” key gets automatically pressed (internally).

You’re not aware of this issue, since you’re focusing on the text and did not even turn on the monitor! After you finished typing, you can see a text on the screen (if you turn on the monitor).

In Chinese, we can call it Beiju. Your task is to find the Beiju text.

Input

There are several test cases. Each test case is a single line containing at least one and at most 100,000 letters, underscores and two special characters ‘[‘ and ‘]’. ‘[‘ means the “Home” key is pressed internally, and ‘]’ means the “End” key is pressed internally. The input is terminated by end-of-file (EOF). The size of input file does not exceed 5MB.

Output

For each case, print the Beiju text on the screen.

Sample Input

This_is_a_[Beiju]_text [[]][][]Happy_Birthday_to_Tsinghua_University

Output for the Sample Input

BeijuThis_is_a__text Happy_Birthday_to_Tsinghua_University

题意 电脑键盘的home键和end键坏了 会在你不注意时自动按下

给你一个输入序列 ‘[‘代表home键 ‘]’代表end键 要求输出屏幕上对应的输出

用链表保存每个位置的字符c和下一个位置的编号next 最后一个字符的next为0

并用cur表示光标的移动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 100005;
char s[N], c;
int cur, last, l;
struct Node{ char c; int next;} lis[N];
int main()
{
while (~scanf ("%s", s + 1))
{
l = strlen (s + 1);
lis[0].next = last = cur = 0;
for (int i = 1; i <= l; ++i)
{
c = s[i];
if (c == '[') cur = 0;
else if (c == ']') cur = last;
else
{
lis[i].c = c;
lis[i].next = lis[cur].next;
lis[cur].next = i;
if (cur == last) last = i;
cur = i;
}
}
for (int i = lis[0].next; i != 0; i = lis[i].next)
printf ("%c", lis[i].c);
printf ("\n");
}
return 0;
}

B. Bargaining Table

Bob wants to put a new bargaining table in his office. To do so he measured the office room thoroughly and drew its plan: Bob’s office room is a rectangular room n × m meters. Each square meter of the room is either occupied by some furniture, or free. A bargaining table is rectangular, and should be placed so, that its sides are parallel to the office walls. Bob doesn’t want to change or rearrange anything, that’s why all the squares that will be occupied by the table should be initially free. Bob wants the new table to sit as many people as possible, thus its perimeter should be maximal. Help Bob find out the maximum possible perimeter of a bargaining table for his office.
Input

The first line contains 2 space-separated numbers n and m (1 ≤ n, m ≤ 25) — the office room dimensions. Then there follow n lines with m characters 0 or 1 each. 0 stands for a free square meter of the office room. 1 stands for an occupied square meter. It’s guaranteed that at least one square meter in the room is free.

Output

Output one number — the maximum possible perimeter of a bargaining table for Bob’s office room.
Sample test(s)

input 3 3 000 010 000

output 8
input 5 4 1100 0000 0000 0000 0000

output 16

HDU 1505,1506的变形 只是由求面积变成了求周长 具体分析可见http://blog.csdn.net/iooden/article/details/38379065

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 30;
int l[N][N], r[N][N], h[N][N], n, m, ans;
char a[N][N];
int main()
{
scanf ("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)
{
h[i][0] = h[i][m + 1] = -1;
scanf ("%s", a[i] + 1);
for (int j = 1; j <= m; ++j)
{
if (a[i][j] == '0') h[i][j] = h[i - 1][j] + 1;
l[i][j] = r[i][j] = j;
}
}
int ans = 0;
for (int i = 1; i <= n; ++i)
{
for (int j = m; j >= 1; --j)
while (h[i][r[i][j] + 1] >= h[i][j]&&h[i][j])
r[i][j] = r[i][r[i][j] + 1];

for (int j = 1; j <= m; ++j)
{
while (h[i][l[i][j] - 1] >= h[i][j]&&h[i][j])
l[i][j] = l[i][l[i][j] - 1];
ans = max (ans, r[i][j] - l[i][j] + 1 + h[i][j]);
}
}
printf ("%d\n", 2 * ans);
return 0;
}

另外这题数据比较小 也可以暴力枚举 枚举每点作为左上角 然后枚举合法的的长和宽, 判断形成的的矩阵是否全由 ‘0’组成, 如果是就更新结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include<cstdio>
#include<cstring>
const int maxn = 30;
int n, m;
int a[maxn][maxn];
int sum[maxn][maxn];
int main()
{
while (~scanf ("%d%d", &n, &m))
{
memset (a, 0, sizeof (a));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf ("%1d", &a[i][j]);
memset (sum, 0, sizeof (sum));
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + a[i][j];
}
}
int x, y;
int ans = 0;
for (int x1 = 1; x1 <= n; x1++)
for (int y1 = 1; y1 <= m; y1++)
for (int x2 = x1; x2 <= n; x2++)
for (int y2 = y1; y2 <= m; y2++)
{
int tmp = sum[x2][y2] + sum[x1 - 1][y1 - 1] - sum[x1 - 1][y2] - sum[x2][y1 - 1];
if (tmp == 0)
{
int dx = x2 - x1 + 1;
int dy = y2 - y1 + 1;
if (ans < (dx + dy) * 2) ans = (dx + dy) * 2;
}
}
printf ("%d\n", ans);
}
return 0;
}
0%