Problem A : STEED Cards
Description
Corn does not participate the STEED contest, but he is interested in the word "STEED". So, Corn writes all permutations of the word "STEED" on different cards and gets 60 cards finally.
Corn sorts these cards in lexicographical order, and marks them from 1 to 60.
Now, Corn gives you a integer N (1 ≤ N ≤ 60), could you tell him the word on the Nth card?
Input
There are multiple test cases (no more than 60).
For each test case, there is one integer N (1 ≤ N ≤ 60) in a line.
Output
For each test case, you should output one line with the word on the Nth card.
Sample Input
1 2 3 4 47 48 49
Sample Output
DEEST DEETS DESET DESTE STEDE STEED TDEES
Author: Corn
题意:Corn将"STEED"按照字典序排列并且给它们编号从1到60,现在给你一个数字N,要求出编号为N的字符串
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
int i=-1,j;
char a[]={'D','E','E','S','T'};
string s[70];
do
{
i++;
for(j=0;j<5;j++)
s[i]+=a[j];
}while(next_permutation(a,a+5));
int n;
while(~scanf("%d",&n))
{
cout<<s[n-1]<<endl;
}
return 0;
}
Problem B : Sailing
Description
Handoku is sailing on a lake at the North Pole. The lake can be considered as a two-dimensional square plane containing N× N blocks, which is shown in the form of string containing '*' and '#' on the map.
- * : a normal block;
- # : a block containing pack ice.
![](http://acm.dhu.edu.cn/images/DHUOJ/acQFgkF38T/XT7LdXhltJ_sailing.png)
Handoku is at (1, 1) initially, and his destination is (N, N). He can only move to one of the four adjacent blocks. Sailing around pack ice is dangerous and stressful, so he needs power to remain vigilant. That means if he moves from a '*' block to a '#' block or moves from a '#' block to any another block, he needs to consume 1 unit power. In other cases, he can enjoy the scene on his boat without consuming any power.
Now Handoku wants to know how many units power will be consumed at least during his sailing on the lake.
Input
There are several test cases (no more than 20).
For each test case, the first line contains a single integer N (3 ≤ N ≤ 50), denoting the size of the lake. For the following Nlines, each line contains a N-length string consisting of '*' and '#', denoting the map of the lake.
Output
For each test case, output exactly one line containing an integer denoting the answer of the question above.
Sample Input
3 **# **# *#* 3 ##* #*# ### 4 **## #**# ##** ###*
Sample Output
2 4 0
Author: handoku
*:代表一个正常的方格
#:代表一个包含冰块的方格
Handoku起初在(1,1)位置并且他的目标是(N,N),他只有四个方向可以移动,在包含冰块的方格附近移动是危险又有压力的所以他需要能量去保持机警,这意味着如果他从'*'到'#'或是从'#'到任意一个方格,都需要花费一单元的能量.在其他情况下不用花费任何能量.现在Handoku想知道他在这次航行中至少要花费多少?
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//四个方向
int n,a[52][52],vis[52][52];
struct node
{
int x,y;
int time;
friend bool operator<(node a,node b)//优先队列优先从小到大
{
return a.time>b.time;
}
}pre,now;
void bfs()
{
priority_queue<node>q;
pre.x=1;
pre.y=1;
pre.time=0;
q.push(pre);
while(!q.empty())
{
now=q.top();
q.pop();
if(now.x==n&&now.y==n)
{
printf("%d\n",now.time);
break;
}
for(int i=0;i<4;i++)
{
pre.x=now.x+dir[i][0];
pre.y=now.y+dir[i][1];
if(pre.x>=1&&pre.x<=n&&pre.y>=1&&pre.y<=n)
{
if(a[pre.x][pre.y]=='#'||a[now.x][now.y]=='#')
pre.time=now.time+1;//如果他从'*'到'#'或是从'#'到任意一个方格,都需要花费一单位的能量
else
pre.time=now.time;//在其他情况下不用花费任何能量
if(vis[pre.x][pre.y]>pre.time)
{//如果再次走过当前点比当前点保存的时间短就更新并入队,而不是说走过一个点就标记不能再走了
vis[pre.x][pre.y]=pre.time;
q.push(pre);
}
}
}
}
}
int main()
{
while(~scanf("%d",&n))
{
int i,j;
for(i=1;i<=n;i++)
{
getchar();//这个地方不要忘了加
for(j=1;j<=n;j++)
scanf("%c",&a[i][j]);
}
memset(vis,INF,sizeof(vis));//用来存放方格中到达当前点所消耗的最小能量
bfs();
}
return 0;
}
Problem C : Count the Number
Description
Given n numbers, your task is to insert '+' or '-' in front of each number to construct expressions. Note that the position of numbers can be also changed.
You can calculate a result for each expression. Please count the number of distinct results and output it.
Input
There are several cases.
For each test case, the first line contains an integer n (1 ≤ n ≤ 20), and the second line contains n integers a1,a2, ... ,an(-1,000,000,000 ≤ ai ≤ 1,000,000,000).
Output
For each test case, output one line with the number of distinct results.
Sample Input
2 1 2 3 1 3 5
Sample Output
4 8
Author: Sherry
请计算不同结果的个数并将其输出.
这个题其实我做的时候是理解题意的,可是做着做着就和题意不太符合了。不过有趣的是就一遍AC了,也算是歪打正着了。
下面把我一不小心AC的代码贴出来(其实能AC也是有一定原因的:因为总的数和是一样的我这样算是把正的数之和都求出来了,
只要保证正的数之和不重复,答案也就是对的了)
思路:这道题我没有用搜索,按照我上面简略介绍的而是用到了二进制,原因不难得出吧。而且我自己觉得这样比较方便。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int aa[21],x[2000005];//x数组用于标记数字是否出现过
void f(int n)//将十进制转化为二进制数字
{
int i=0;
while(n!=0)
{
aa[i++]=n%2;
n/=2;
}
}
int main()
{
int n,a[25],k,b[21]={0},s[25]={0},l;
b[0]=1,s[0]=1;
for(k=1;k<20;k++)
{
b[k]=b[k-1]*2;//b数组存放2的次幂
s[k]=s[k-1]+b[k];//s数组存放前n项2的次幂之和
}
while(~scanf("%d",&n))
{
int i,j,c=0;
memset(x,0,sizeof(x));
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<=s[n-1];i++)
{
l=0;
memset(aa,0,sizeof(aa));//每次初始化
f(i);//得到当前数字的二进制,得到各种'+'或'-'插入的可能的结果
for(j=0;j<n;j++)
l+=aa[j]*a[j];
if(x[l]==0)
{
x[l]=1;
c++;//存放最后结果
}
}
printf("%d\n",c);
}
return 0;
}
所以这个二进制的作用明白了吧
Problem E : Find Palindrome
Description
Given a string S, which consists of lowercase characters, you need to find the longest palindromic sub-string.
A sub-string of a string S is another string S' that occurs "in" S. For example, "abst" is a sub-string of "abaabsta". A palindrome is a sequence of characters which reads the same backward as forward.
Input
There are several test cases.
Each test case consists of one line with a single string S (1 ≤ |S | ≤ 50).
Output
For each test case, output the length of the longest palindromic sub-string.
Sample Input
sasadasa bxabx zhuyuan
Sample Output
7 1 3
Author: Kenny
思路:我是按照求两个字符串的最大公共字串的方法来实现的,当然一个字符串的最大回文字串和两个字符串的最大公共字串是不一样的。只要再加一个判断条件就可以了(主要是因为位置原因,一个字符串的最大回文字串位置较于两个字符串的最大公共字串更死板一些,所以在求两个字符串的最大公共字串长度时再加一个判断条件就行了)
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
char a[100],b[100];
int dp[100][100];
while(gets(a))
{
int i,j,len,maxn=0;
len=strlen(a);
for(i=0;i<len;i++)
b[i]=a[len-1-i];//将a字符串反过来
memset(dp,0,sizeof(dp));
for(i=1;i<=len;i++)
for(j=1;j<=len;j++)
{
if(a[i-1]==b[j-1])
dp[i][j]=dp[i-1][j-1]+1;
if(dp[i][j]>maxn&&len-i==j-dp[i][j]&&len-(i-dp[i][j])-1==j-1)//注意这里的判断条件就是我所强调的
maxn=dp[i][j];
}
printf("%d\n",maxn);
}
return 0;
}
Problem I : Frog's Jumping
Description
There are n lotus leaves floating like a ring on the lake, which are numbered 0, 1, ..., n-1 respectively. The leaf 0 and n-1 are adjacent.
The frog king wants to play a jumping game. He stands at the leaf 0 initially. For each move, he jumps k (0 < k < n) steps forward. More specifically, if he is standing at the leaf x, the next position will be the leaf (x + k) % n.
After n jumps, he wants to go through all leaves on the lake and go back to the leaf 0 finally. He can not figure out how many different k can be chosen to finish the game, so he asks you for help.
![](http://acm.dhu.edu.cn/images/DHUOJ/RBVKlhF3qw/Dx1SLCzuRx_frog.jpg)
Input
There are several test cases (no more than 25).
For each test case, there is a single line containing an integer n (3 ≤ n ≤ 1,000,000), denoting the number of lotus leaves.
Output
For each test case, output exactly one line containing an integer denoting the answer of the question above.
Sample Input
4 5
Sample Output
2 4
Author: handoku
思路:我开始只是想用模拟试试结果还被周围的人嘲笑了,当然这次尝试以失败告终。
因为数据太大,后来是用找规律做的。只要是n的约数的倍数都不满足条件,去掉这些都是满足条件的了。证明可以自行尝试,这里就只说结论了。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int a[1000005];
int main()
{
int n;
while(~scanf("%d",&n))
{
int i,j=0,m=n-1;//
memset(a,0,sizeof(a));
for(i=2;i<n;i++)
{
if(n%i==0)//满足是约数
{
for(j=1;j*i<n;j++)
if(a[j*i]==0)//约数的倍数
{
a[j*i]=1;//因为约数的倍数可能会有重复,所以用到标记数组
m--;
}
}
}
printf("%d\n",m);
}
return 0;
}
Problem O : An Easy Problem
Description
Zhu Ge is a very clever boy. One day, he discovered 2*n numbers. He wanted to divide them into n groups, each group contains 2 integers, and minimize the sum of the absolute value of the difference of the numbers in each group.
The problem is too difficult to Zhu Ge, so he turned to you. He hopes you can calculate the minimum of the sum of absolute value of the difference among different division strategies.
Input
There are several test cases.
For each test case, there is an integer n (n < 10,000) at the first line. The second line contains 2*n integers. The input ends up with EOF.
Output
For each test case, output the minimum of sum.
Sample Input
3 10 3 4 5 1 6 5 64 5 63 63 23 63 54 64 3 54
Sample Output
7 42
Author: Kuang
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
int n;
long long int a[30005];
while(~scanf("%d",&n))
{
int i;
for(i=0;i<2*n;i++)
scanf("%lld",&a[i]);
sort(a,a+2*n);
long long int s=0;
for(i=0;i<2*n;i+=2)
s+=a[i+1]-a[i];
printf("%lld\n",s);
}
return 0;
}