刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第五章 3(Sorting/Searching)

第一题:340 - Master-Mind Hints

UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=276

题目大意:给定密码长度,然后是密码占一行,然后每一行是一个猜测,需要找出这行猜测有几个位置相同且密码相同的个数,几个位置不同但密码匹配的个数;前者个数为A,后者个数为B,匹配优先前者比如说密码为 1 2 3 4,猜测为 2 2 1 3,则A = 1, B = 2。读入直到猜测都为0。

解题思路: 先找位置相同的匹配并标记为已匹配,然后找不同位置的匹配,找到一个标记一个。

解题代码:

 //#define LOCAL  //Please annotate this line when you submit
#ifdef WINDOWS
#define LL __int64
#define LLD "%I64d"
#else
#define LL long long
#define LLD "%lld"
#endif
/********************************************************/
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
using namespace std;
const int max_n = ; int s[max_n];
bool had_s[max_n], had_g[max_n];
int g[max_n]; int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
int n;
int total;
int a, b;
int T = ;
while (~scanf ("%d", &n) && n)
{
printf("Game %d:\n", T ++);
for (int i = ; i < n; i ++)
scanf("%d", &s[i]);
while ()
{
total = ;
memset(had_s, false, sizeof(had_s));
memset(had_g, false, sizeof(had_g));
a = b = ;
for (int i = ; i < n; i ++)
{
scanf ("%d", &g[i]);
total += g[i];
}
if (!total)
break;
for (int i = ; i < n; i ++)
{
if (g[i] == s[i])
{
a ++;
had_s[i] = true;
had_g[i] = true;
}
}
for (int i = ; i < n; i ++)
{
for (int j = ; j < n; j ++)
{
if (g[i] == s[j] && !had_s[j] && !had_g[i])
{
b ++;
had_s[j] = true;
had_g[i] = true;
break;
}
}
}
printf(" (%d,%d)\n", a, b);
} }
return ;
}

第二题:10420 - List of Conquests

Uva:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=1361

题目大意:找出来自同一城市的美女,首先输入人数n,然后n行,每行第一个单词即为美女所在城市,统计来自同一城市的人数,并按字典序输出城市名与来自此城市的人数。

解题思路:直接匹配即可。

解题代码:

 // File Name    :10420 - List of Conquests
// Author :Freetion #include <stdio.h>
#include <iostream>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std; const int max_n = ;
int main()
{
char name[];
string str[max_n];
int n;
while (scanf("%d", &n) == )
{
getchar();
for (int i = ; i < n; i ++)
{
gets(name);
str[i].clear();
int len = strlen(name);
for (int j = ; name[j] != ' '; j ++)
str[i] += name[j]; }
sort(str, str+n);
int sum = ;
string tm = str[];
for (int i = ; i < n; i ++)
{
if (str[i] == tm)
sum ++;
else
{
cout << tm;
printf(" %d\n", sum);
tm.clear();
tm = str[i];
sum = ;
}
}
cout << tm;
printf(" %d\n", sum); }
}

第三题:10474 - Where is the Marble?

Uva:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=1415

题目大意:给你大理石的数量,以及询问次数,然后输入石块大小,石块大小是无序输入的,但之前是从小到大都已经编号,然后是询问,每次询问一个数即石块的大小,这么大的石块的编号是多少,并输出。水题,排序,查找。

解题代码:

 // File Name    :10474.cpp
// Author :Freetion //#define LOCAL //Please annotate this line when you submit
/********************************************************/
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
#define CLE(name) memset(name, 0, sizeof(name))
using namespace std; const int max_n = ;
int mar[max_n]; int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
int n, q, x;
int T = ;
while (~scanf("%d%d", &n, &q) && (n + q))
{
printf("CASE# %d:\n", T ++);
for (int i = ; i < n; i ++)
scanf("%d", &mar[i]);
sort(mar, mar+n);
for (int i = ; i < q; i ++)
{
scanf ("%d", &x);
int j;
for (j = ; j < n; j ++)
{
if (x == mar[j])
{
printf("%d found at %d\n", x, j+);
break;
}
}
if (j == n)
printf("%d not found\n", x);
}
}
return ;
}

第四题:152 - Tree's a Crowd

Uva:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=88

题目大意;相当于给你多个三维空间点的坐标,选取一个点找到到该点的最小距离,并将拥有这个最小距离的点数+1,直到取完所有的点,然后输出,距离为0,1,2,3,4,5,6,7,8,9的点数。

解题思路;水题,直接计算即可;

解题代码:

 // File Name    :152 - Tree's a Crowd.cpp
// Author :Freetion //#define LOCAL //Please annotate this line when you submit
/********************************************************/
#include <iostream> #include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
#define CLE(name) memset(name, 0, sizeof(name))
using namespace std; const int max_n = ;
struct Point
{
int x, y, z;
int operator - (const Point p) const
{
int ans;
ans = (int)sqrt((x - p.x)*(x - p.x) + (y - p.y)*(y - p.y) + (z - p.z)*(z - p.z));
return ans;
}
}point[max_n]; int main()
{
int x, y, z;
int num = ;
int dis[];
CLE(dis);
while (~scanf("%d%d%d", &x, &y, &z) && (x+y+z))
{
point[num ++] = (Point){x, y, z};
}
for (int i = ; i < num; i ++)
{
int min = 0x3fffffff;
for (int j = ; j < num; j ++)
{
if (i == j)
continue;
int tm = point[i] - point[j];
if (min > tm)
min = tm;
}
dis[min] ++;
}
for (int i = ; i < ; i ++)
printf("%4d", dis[i]);
puts("");
}

第五题:299 - Train Swapping

Uva:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=235

题目大意:一辆列车,相邻的两节车厢可以交换,要你找出最小的交换次数,使得列车按升序排列;

解题思路:写个冒泡排序即可;

解题代码:

 // File Name    :299.cpp
// Author :Freetion #define LOCAL //Please annotate this line when you submit
/********************************************************/
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
#define CLE(name) memset(name, 0, sizeof(name))
using namespace std; int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
int T, n;
int tra[];
scanf("%d", &T);
while (T--)
{
scanf ("%d", &n);
for (int i = ; i < n; i ++)
scanf ("%d", &tra[i]);
int ans = ;
for (int i = ; i < n-; i ++)
{
for (int j = i+; j < n; j ++)
{
if (tra[i] > tra[j])
{
tra[i] = tra[i]^tra[j];
tra[j] = tra[j]^tra[i];
tra[i] = tra[i]^tra[j];
ans ++;
}
}
}
printf("Optimal train swapping takes %d swaps.\n", ans);
}
}

第六题:120 - Stacks of Flapjacks

Uva:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=56

题目大意:给你一堆煎饼,每个煎饼半径各不相同,位置为n的地方相当于锅的低端,然后然你的刀从中间某一位插进去进行翻转,当然只能向上翻转,然后找出最少的次数使得煎饼大小从小到大排列,并依次输出翻转的位置,直到不用进行翻转,输出位置0,由于是逆序,所以,位置为n的地方相当于位置1,反之亦然;

解题思路:每次找到半径最大的煎饼位置(如果它已经在它本应呆的位置则跳过)往上翻转到顶端,如果已经在顶端,则不翻转,然后找到它本应呆的位置在翻转,然后循环直到所有的都排好序,由于输出还要有原顺序,所以需要两个数组保存数据,一个用来做,另一个输出。

解题代码:

 // File Name    :120 - Stacks of Flapjacks.cpp
// Author :Freetion #define LOCAL //Please annotate this line when you submit
/********************************************************/
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
#define CLE(name) memset(name, 0, sizeof(name))
using namespace std; const int max_n = ;
int sta[max_n], fu[max_n]; int main()
{
char str[*max_n];
int pos[max_n], temp[max_n];
while (gets(str))
{
int len = strlen(str);
int cun = ;
CLE(sta);
for (int i = ; i < len; i ++)
{
while(str[i] != ' ' && i < len)
{
sta[cun] = sta[cun]* + str[i] - '';
i ++;
}
fu[cun] = sta[cun];
cun ++; }
for(int i = ; i < cun; i ++)
{
// cout << sta[i] << " ";
temp[i] = sta[i];
}
sort(temp+, temp+cun);
int re = ;
int last = cun - ;
for (int i = cun - ; i >= ; i --)
{
int M = temp[i];
for (int j = i; j >=; j--)
{
if (M == sta[j])
{
if (j == i)
break;
if (j != )
{
pos[re++] = j;
for (int k = ; k <= j/; k ++)
{
sta[k] = sta[k] ^ sta[j-k+];
sta[j-k+] = sta[j-k+] ^ sta[k];
sta[k] = sta[k] ^ sta[j-k+]; }
}
pos[re++] = i;
for (int k = ; k <= i/; k ++)
{
sta[k] = sta[k] ^ sta[i-k+];
sta[i-k+] = sta[i-k+] ^ sta[k];
sta[k] = sta[k] ^ sta[i-k+]; }
break;
} }
}
for (int i = ; i < cun; i ++)
printf("%d%c", fu[i], i != cun- ? ' ' : '\n');
for (int i = ; i < re; i ++)
printf("%d ", cun - pos[i]);
printf("0\n");
}
return ;
}

第七题:156 - Ananagrams

uva:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=92

题目大意:给你一段文字,以#键结束,找出中间每个单词以任何顺序排列都没有出现第二次的单词;

解题思路:刚开始想到排列组合,但是发现很不现实,百度一下才知将每个单词转换成小写字母,然后以字典序排好,依次比较看有没有重复的,有即标记,最后输出没有标记的单词,但是要是原单词,所以这题也许两个数组,存储单词。由于要按字典序输出单词,所以我们需要先排序后判断。

解题代码:

 //#define LOCAL  //Please annotate this line when you submit
#ifdef WINDOWS
#define LL __int64
#define LLD "%I64d"
#else
#define LL long long
#define LLD "%lld"
#endif
/********************************************************/
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
#define CLE(name, a) memset(name, a, sizeof(name))
using namespace std; const int max_w = ;
const int max_l = ;
string word[max_w], deel[max_w];
char temp[max_l];
bool have[max_w];
int cun; void solve()
{
for (int k = ; k < cun-; k ++)
{
int len = word[k].length();
for (int i = ; i < len; i ++)
{
if (word[k][i] <= 'Z')
temp[i] = word[k][i] + ;
else temp[i] = word[k][i]; }
sort(temp, temp+len);
deel[k] = "";
for (int i = ; i < len; i ++)
deel[k] += temp[i];
for (int i = ; i < k; i ++)
{
int tm = deel[i].length();
if (tm == len)
{
int j;
for (j = ; j < len; j ++)
{
if (deel[i][j] != deel[k][j])
break;
}
if (j == len)
{
have[i] = true;
have[k] = true;
}
}
}
}
} int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
cun = ;
CLE(have, false);
while (cin >> word[cun ++])
{
if (word[cun-][] == '#')
break;
}
sort(word, word+cun-);
solve();
for (int i = ; i < cun-; i ++)
{
if (!have[i] == )
cout << word[i] << endl;
}
return ;
}

第八题:400 - Unix ls

uva:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=341

题目大意:输入整数n,然后n行,每行一个文件名,输出:将文件按字典序排序,然后按列优先的顺序,输出每行所占字符不超过60个,每列之间的间距以最长文件名加上两个字符的长度为准。

解题思路:此题不难,但输出需要控制好,此题很容易RE,原因可能是数组开得小,以0为除数等,此题要求所占字符不超过60,但是应该有数据的长度刚好是60,再加上 2,就可能造成数组开61的越界,也就RE,而我就是以0为除数造成RE。

解题代码:

 #define LOCAL  //Please annotate this line when you submit
#ifdef WINDOWS
#define LL __int64
#define LLD "%I64d"
#else
#define LL long long
#define LLD "%lld"
#endif
/********************************************************/
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
using namespace std;
const int max_n = ;
string file[max_n]; int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
int n;
int max_l;
int x, y;
while (~scanf("%d", &n))
{
max_l = ;
for (int i = ; i < n; i ++)
{
cin >> file[i];
if (max_l < file[i].length())
max_l = file[i].length();
}
sort(file, file+n);
max_l += ;
printf("------------------------------------------------------------\n");
x = max_l > ? : /max_l;//处理加上2之后的最大长度超过60的情况。如果不处理就会使得x为0,再用x作为除数就会出现RE
y = n/x;
if (n%x)
y ++;
for (int i = ; i < y; i ++ )
{
for (int j = ; j < x; j ++)
{
if (i+j*y < n)
{
int len = file[i+j*y].length();
cout << file[i+j*y];
for (int k = len+; k <= max_l; k ++)
printf(" ");
}
}
printf("\n");
}
}
return ;
}

第九题:123 - Searching Quickly

uva:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=59

题目大意:首先输入多个单词,以::结束;然后给几句话,直到EOF,找出::以前没有出现过的单词作为关键字,然后将关键字按字典序排序,按关键词的顺序,输出句子中出现过了关键词的句子,并且关键字要大写,一个句子中出现过多次同一关键字,也要依次输出多次,每次将对应的关键字大写。

解题思路:这题也水,只是输出的处理而已。

解题代码:

 #define LOCAL  //Please annotate this line when you submit
#ifdef WINDOWS
#define LL __int64
#define LLD "%I64d"
#else
#define LL long long
#define LLD "%lld"
#endif
/********************************************************/
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
using namespace std;
const int max_n = ;
string key_w[max_n], tm;
char input[][max_n];
char ign_w[][]; int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
bool ign = true;
int ign_num = ;
int key_num = ;
int input_num = ;
char *need;
while (scanf ("%s", ign_w[ign_num]) != EOF)
{
for (int i = ; i < strlen(ign_w[ign_num]); i ++)
if (ign_w[ign_num][i] <= 'Z' && ign_w[ign_num][i] >= 'A')
ign_w[ign_num][i] += ;
ign_num ++;
if (ign_w[ign_num-][] == ':')
{
ign_num --;
break;
}
}
while(gets(input[input_num++]))
{
int len = strlen(input[input_num-]);
for (int i = ; i < len; i ++)
{
if (input[input_num-][i] <= 'Z' && input[input_num-][i] >= 'A')
input[input_num-][i] += ;
if (input[input_num-][i] != ' ')
tm += input[input_num-][i];
if (input[input_num-][i] == ' ' || i == len-)
{
int j;
for (j = ; j < key_num; j ++)
{
int len_t = tm.length();
int len_k = key_w[j].length();
if (len_t == len_k)
{
int pos;
for (pos = ; pos < len_t; pos++)
{
if (tm[pos] != key_w[j][pos])
break;
}
if (pos == len_t)
break; }
}
if (j == key_num)
{
int k;
for (k = ; k < ign_num; k ++)
{
int len_i = strlen(ign_w[k]);
int len_t = tm.length();
if (len_i == len_t)
{
int pos;
for (pos = ; pos < len_t; pos ++)
if (tm[pos] != ign_w[k][pos])
break;
if (pos == len_t)
break;
}
}
if (k == ign_num)
key_w[key_num++] = tm;
}
tm.clear();
}
}
}
sort(key_w, key_w+key_num);
for (int i = ; i < key_num; i ++)
{
int len_k = key_w[i].length();
for (int j = ; j < input_num; j ++)
{
int len_in = strlen(input[j]);
for (int k = ; k < len_in; k ++)
{
if (k == || input[j][k-] == ' ')
{
int pos = ;
while (pos < len_k)
{
if (input[j][k] != key_w[i][pos])
break;
pos ++;
k ++;
}
if (pos == len_k && (input[j][k] == ' ' || input[j][k] == '\0'))
{
for (int out = ; out < len_in; out ++)
{
if (out >= k - pos && out < k)
{
printf("%c", input[j][out] - );
continue;
}
printf("%c", input[j][out]);
}
printf("\n");
}
k = k - pos;
}
} }
}
return ;
}

第十题:10194 - Football (aka Soccer)

uva:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=1135

题目大意:(转载)http://blog.sina.com.cn/s/blog_867764f70100t5p6.html

此题题目较长,题意较难理解。

The Problem

问题。

So, your task is quite simple: write a program that receives the tournament name, team names and games played and outputs the tournament standings so far.

因此,你的任务相当简单:写一个程序,输入锦标赛(tournament)的名字、足球队的名字和踢的比赛,输出锦标赛最后的成绩。

A team wins a game if it scores more goals than its oponent. Obviously, a team loses a game if it scores less goals. When both teams score the same number of goals, we call it a tie. A team earns 3 points for each win, 1 point for each tie and 0 point for each loss.

如果一个队进球数(不是得分)比它的对手多,那么这个队就赢了这场比赛。很明显,如果进球数比对手少,就输了比赛。两个队进球数相同,就打平了。每赢一次,一个队就获得3分;平一次,就获得1分;输一次,得0分。

Teams are ranked according to these rules (in this order):

球队以下面的规则排名(优先性递减)

Most points earned.    分数最多

Most wins.      赢得次数最多

Most goal difference (i.e. goals scored - goals against)   净进球数最多

Most goals scored.   进球数最多

Less games played.   参赛次数最少

Lexicographic order.  参赛队名按字母序(不区分大小写)

The first line of input will be an integer N in a line alone (0 < N < 1000). Then, will follow N tournament descriptions. Each one begins with the tournament name, on a single line. Tournament names can have any letter, digits, spaces etc. Tournament names will have length of at most 100. Then, in the next line, there will be a number T (1 < T <= 30), which stands for the number of teams participating on this tournament. Then will follow T lines, each one containing one team name. Team names may have any character that have ASCII code greater than or equal to 32 (space), except for '#' and '@' characters, which will never appear in team names. No team name will have more than 30 characters.

输入:第一行是一个整数N(0 < N < 1000),之后是N个锦标赛的描述。

每个锦标赛开始是锦标赛的名字,占一行,可以有任何字母、数字、空格等等,长度不超过100个字符;接下来的一行是一个整数T(1 < T <= 30),代表参赛球队的个数;接下来的T行,每行有一个队名,除了‘#’和‘@’外,所有字符ASCII码均大于或等于32,长度不超过30.

Following to team names, there will be a non-negative integer G on a single line which stands for the number of games already played on this tournament. G will be no greater than 1000. Then, G lines will follow with the results of games played. They will follow this format:

接下来的一行有一个非负整数G(<1000),代表比赛的个数,然后有G行比赛结果,形式如下:

team_name_1#goals1@goals2#team_name_2

For instance, the following line:

例如下面的一行:

Team A#3@1#Team B

Means that in a game between Team A and Team B, Team A scored 3 goals and Team B scored 1. All goals will be non-negative integers less than 20.

表示在球队A和球队B之间有场比赛,A进3个球(不是获得3分),B进1个球。所有球数均是小于20的非负整数。

For each tournament, you must output the tournament name in a single line. In the next T lines you must output the standings, according to the rules above. The output format for each line is shown bellow:

输出:对每个锦标赛,输出它的名字在一行。接下来的T行,基于上面的规则输出最终的成绩,输出形式如下:

[a]) Team_name [b]p, [c]g ([d]-[e]-[f]), [g]gd ([h]-[i])

其中:

[a] = team rank 排名

[b] = total points earned  总得分(不是进球数)

[c] = games played  踢的场数

[d] = wins  赢的个数

[e] = ties 平的个数

[f] = losses  输的个数

[g] = goal difference   净进球数(进球数—输球数)

[h] = goals scored   进球数

[i] = goals against  输球数(对手进球数)

注意:(1)进球数(goals scored)和得分(points)不是一个概念,注意区别。

(2)对球队名排序时不区分大小写,一定要注意。(我就因为这点没注意,WA了好多次)

(3)You may assume that there will not be inexistent team names (i.e. all team names that appear on game results will have apperead on the team names section) and that no team will play against itself.

可以认为,不会有不存在的球队出现(比赛结果上的所有球队名都在开始输入的球队名单上),不会出现比赛双方是一个球队。

(4)按规则对最终结果排序时,一定要注意优先顺序。

以上是转载

解题代码:

 #define LOCAL  //Please annotate this line when you submit
#ifdef WINDOWS
#define LL __int64
#define LLD "%I64d"
#else
#define LL long long
#define LLD "%lld"
#endif
/********************************************************/
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
using namespace std;
char name[];
struct node
{
int total_goal, games_num, wins, ties;
int losses, goal_dif, goal_ball, lose_ball;
string team;
bool operator < (const node G) const //重载 < 符号便于使用sort函数
{
if (total_goal == G.total_goal)
{
if (wins == G.wins)
{
if (goal_dif == G.goal_dif)
{
if (goal_ball == G.goal_ball)
{
if (games_num == G.games_num)
{
int len1 = team.length();
int len2 = G.team.length();
int i;
for (i = ; i < len1; i ++) //不区分大小写按字典序排列
{
if (i >= len2)
break;
char ch1 = team[i];
char ch2 = G.team[i];
if (ch1 <= 'Z')
ch1 += ;
if (ch2 <= 'Z')
ch2 += ;
if (ch1 < ch2)
return true;
else if (ch1 > ch2)
return false;
}
if (i == len1)
return true;
else return false;
}
return games_num < G.games_num;
}
return goal_ball > G.goal_ball;
}
return goal_dif > G.goal_dif;
}
return wins > G.wins;
}
return total_goal > G.total_goal;
}
}all_team[]; int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
int T, n, pk;
char tmp[];
scanf ("%d", &T);
getchar();
while ( T-- )
{
gets(name);
puts(name);
scanf ("%d", &n);
getchar();
for (int i = ; i < n; i ++)
{
all_team[i] = (node){,,,,,,,};//初始化每个球队的数据,不能放到gets()之后。
gets(tmp);
for (int j = ; j < strlen(tmp); j ++)
all_team[i].team += tmp[j];
}
scanf ("%d", &pk);
getchar();
for (int i = ; i < pk; i ++)
{
gets(tmp);
int len = strlen(tmp);
string team_1, team_2;
int get_1 = , get_2 = ;
int ch1 = , ch2 = ;
int one_win_2 = ;
for (int j = ; j < len; j ++)
{
if (tmp[j] == '#')
{
ch1 ++;
continue;
}
if (tmp[j] == '@')
{
ch2 ++;
continue;
}
if (ch1 == )
team_1 += tmp[j];
if (ch1 == && ch2 == )
get_1 = get_1* + tmp[j] - '';
if (ch1 == && ch2 == )
get_2 = get_2* + tmp[j] - '';
if (ch1 == )
team_2 += tmp[j];
}
if (get_1 == get_2)
one_win_2 = ;
else if (get_1 < get_2)
one_win_2 = ;
for (int j = ; j < n; j ++)
{
node& A = all_team[j];
if (team_1 == A.team)
{
if (one_win_2 == )
{
A.total_goal += ;
A.wins ++;
}
else if (one_win_2 == )
{
A.total_goal += ;
A.ties ++;
}
else A.losses ++;
A.games_num ++;
A.goal_dif += (get_1 - get_2);
A.goal_ball += get_1;
A.lose_ball += get_2;
}
else if (team_2 == A.team)
{
if (one_win_2 == )
{
A.total_goal += ;
A.wins ++;
}
else if (one_win_2 == )
{
A.total_goal += ;
A.ties ++;
}
else A.losses ++;
A.games_num ++;
A.goal_dif += (get_2 - get_1);
A.goal_ball += get_2;
A.lose_ball += get_1;
}
}
}
sort(all_team, all_team+n);//排序
for (int i = ; i < n; i ++)
{
node A = all_team[i];
printf("%d) ", i+);
cout << all_team[i].team;
printf(" %dp, %dg (%d-%d-", A.total_goal, A.games_num, A.wins, A.ties);
printf("%d), %dgd (%d-%d)\n", A.losses, A.goal_dif, A.goal_ball, A.lose_ball);
}
if (T)
printf("\n");
}
return ;
}

第十一题:755 - 487--3279(此题submition error)

解题思路:转换成数字。

解题代码:

 #include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <iostream>
#include<iomanip>
#include <map>
using namespace std;
const int max_n = 1e5+; string str ;
int str3[max_n]; void change(int n)
{
int k = ;
for (int i = ; i < n; i ++)
{
str.clear();
cin >> str;
int len = str.length();
str3[i] = ;
for (int j = ; j < len; j ++)
{
if (str[j] != '-' && str[j] <= 'Z')
str3[i] *= ;
switch (str[j])
{
case '': str3[i] += ; break;
case '': str3[i] += ; break;
case '':
case 'A':
case 'B':
case 'C': str3[i] += ; break;
case '':
case 'D':
case 'E':
case 'F': str3[i] += ; break;
case '':
case 'G':
case 'H':
case 'I': str3[i] += ; break;
case '':
case 'J':
case 'K':
case 'L': str3[i] += ; break;
case '':
case 'M':
case 'N':
case 'O': str3[i] += ; break;
case '':
case 'P':
case 'R':
case 'S': str3[i] += ; break;
case '':
case 'T':
case 'U':
case 'V': str3[i] += ; break;
case '':
case 'W':
case 'X':
case 'Y': str3[i] += ; break;
}
}
// cout << str3[i] << endl;
}
return;
} int main ()
{
int n;
int T;
scanf ("%d", &T);
while (T--)
{
scanf ("%d", &n);
change(n);
sort(str3, str3+n);
int k = ;
for (int i = ; i < n;)
{
int time = ;
bool flag = false;
int x = str3[i];
while(x == str3[i] && i < n)
{
time ++;
i ++;
if (time == )
flag = true;
}
if (flag)
{
k = ;
cout<<setfill('')<<setw()<<str3[i-]/;
cout<<'-';
cout<<setfill('')<<setw()<<str3[i-]%;
cout<<' '<< time <<endl;
flag = false;
time = ;
}
}
if ( k )
printf ("No duplicates.\n");
if (T)
printf("\n");
}
return ;
}

第十二题:10785 - The Mad Numerologist

题目大意:给出元音字母与辅音字母的价值,给定长度,在限定长度的条件下,输出价值总和最小的,且元音字母位于奇数位,辅音位于偶数位,且字典序最小的。

元音字母最多出现21次,辅音字母最多出现5次;ps当n=211时首字母会缺少,其余正常。

解题思路:把元音字母出现的顺序保存到一个数组中,辅音字母也一样保存于另一数组中,然后取出需要的长度排序,再依次输出。

解题代码:

 //#define LOCAL  //Please annotate this line when you submit
#ifdef WINDOWS
#define LL __int64
#define LLD "%I64d"
#else
#define LL long long
#define LLD "%lld"
#endif
/********************************************************/
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
using namespace std;
const char vow[] = {"AUEOI"};//依次顺序,下同
const char cons[] = {"JSBKTCLDMVNWFXGPYHQZR"};
char ans1[], ans2[]; void deel(int n)
{
int v = , c = ;
int get1 = , get2 = ;
for (int i = ; i <= n; i ++)
{
if (i&)
{
ans1[v ++] = vow[get1];
if (v% == )
get1 ++;
}
else
{
ans2[c ++] = cons[get2];
if (c% == )
get2++;
}
} } int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
int x, y;
int T, n, t;
scanf ("%d", &T);
t = T;
while (T--)
{
scanf ("%d", &n);
deel(n);//取出需要的字符
printf("Case %d: ", t - T);
x = y = n/;//各自需要的长度。
int v = , c = ;
if (n&)
x ++;
sort(ans1, ans1+x);
sort(ans2, ans2+y); for (int i = ; i <= n; i ++)
{
printf("%c", ans1[v++]);
i ++;
if (i <= n)
printf("%c", ans2[c++]);
}
puts("");
}
return ;
}

上一篇:[置顶] PHP开发实战权威指南-读书总结


下一篇:刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第五章 1(String)