比赛链接:http://codeforces.com/contest/544
A. Set of Strings
time limit per test:1 second
memory limit per test:256 megabytes
You are given a string q. A sequence of
k strings s1,?s2,?...,?sk is called
beautiful, if the concatenation of these strings is string
q (formally, s1?+?s2?+?...?+?sk?=?q) and the first
characters of these strings are distinct.
Find any beautiful sequence of strings or determine that the
beautiful sequence doesn‘t exist.
Input
The first line contains a positive integer
k (1?≤?k?≤?26) — the number of strings that should be in a
beautiful sequence.
The second line contains string
q, consisting of lowercase Latin letters. The length of the string is within range from
1 to 100, inclusive.
Output
If such sequence doesn‘t exist, then print in a single line "NO" (without the quotes). Otherwise, print in the first line "YES" (without the quotes) and in the next
k lines print the
beautiful sequence of strings s1,?s2,?...,?sk.
If there are multiple possible answers, print any of them.
Sample test(s)
Input
1 abca
Output
YES abca
Input
2 aaacas
Output
YES aaa cas
Input
4 abc
Output
NO
Note
In the second sample there are two possible answers:
{"aaaca",?"s"} and
{"aaa",?"cas"}.
题目大意:把一个给定的母串分成k个子串,要求k个子串的和为母串,且k个子串的首字符不能相同
题目分析:标记一下首字符出现的情况再统计一下分成的份数即可
#include <cstdio> #include <iostream> #include <string> #include <cstring> using namespace std; int main() { int k; cin >> k; string s; cin >> s; string ans[30]; int cnt = 1; int len = s.length(); bool hash[400]; memset(hash, false, sizeof(hash)); bool flag = false; for(int i = 0; i < len; i++) { if(!hash[s[i]]) { hash[s[i]] = true; ans[cnt ++] += s[i]; } else if(hash[s[i]] || s[i] == s[i - 1]) ans[cnt - 1] += s[i]; if(cnt == k + 1) { for(int j = i + 1; j < len; j++) ans[cnt - 1] += s[j]; flag = true; break; } } if(!flag) printf("NO\n"); else { printf("YES\n"); for(int i = 1; i < cnt; i++) cout << ans[i] << endl; } }
B. Sea and Islands
time limit per test:1 second
memory limit per test:256 megabytes
A map of some object is a rectangular field consisting of
n rows and n columns. Each cell is initially occupied by the sea but you can cover some some cells of the map with sand so that exactly
k islands appear on the map. We will call a set of sand cells to be
island if it is possible to get from each of them to each of them by moving only through sand cells and by moving from a cell only to a side-adjacent cell. The cells are called to be side-adjacent if they share a vertical
or horizontal side. It is easy to see that islands do not share cells (otherwise they together form a bigger island).
Find a way to cover some cells with sand so that exactly
k islands appear on the
n?×?n map, or determine that no such way exists.
Input
The single line contains two positive integers
n, k (1?≤?n?≤?100,
0?≤?k?≤?n2) — the size of the map and the number of islands you should form.
Output
If the answer doesn‘t exist, print "NO" (without the quotes) in a single line.
Otherwise, print "YES" in the first line. In the next
n lines print the description of the map. Each of the lines of the description must consist only of characters
‘S‘ and ‘L‘, where
‘S‘ is a cell that is occupied by the sea and
‘L‘ is the cell covered with sand. The length of each line of the description must equal
n.
If there are multiple answers, you may print any of them.
You should not maximize the sizes of islands.
Sample test(s)
Input
5 2
Output
YES SSSSS LLLLL SSSSS LLLLL SSSSS
Input
5 25
Output
NO
题目大意:把一个区域分成k个岛输出方案,岛就是一个四个方向的连通块
题目分析:隔一格,填一个岛,填到k个为止,注意最多可能出现的岛的个数为(n * n + 1) / 2
#include <cstdio> int main() { int n, k; scanf("%d %d", &n, &k); if((n * n + 1) / 2 < k) printf("NO\n"); else { printf("YES\n"); for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if((i + j) % 2 == 0 && k > 0) { printf("L"); k --; } else printf("S"); } printf("\n"); } } }
C. Writing Code
time limit per test:3 seconds
memory limit per test:256 megabytes
Programmers working on a large project have just received a task to write exactly
m lines of code. There are
n programmers working on a project, the i-th of them makes exactly
ai bugs in every line of code that he writes.
Let‘s call a sequence of non-negative integers
v1,?v2,?...,?vn a
plan, if v1?+?v2?+?...?+?vn?=?m. The programmers follow
the plan like that: in the beginning the first programmer writes the first
v1 lines of the given task, then the second programmer writes
v2 more lines of the given task, and so on. In the end, the last programmer writes the remaining lines of the code. Let‘s call a plan
good, if all the written lines of the task contain at most
b bugs in total.
Your task is to determine how many distinct
good plans are there. As the number of plans can be large, print the remainder of this number modulo given positive integer
mod.
Input
The first line contains four integers
n, m,
b, mod (1?≤?n,?m?≤?500,
0?≤?b?≤?500; 1?≤?mod?≤?109?+?7) — the number of programmers, the number of lines of code in the task, the maximum total number of bugs respectively
and the modulo you should use when printing the answer.
The next line contains n space-separated integers
a1,?a2,?...,?an (0?≤?ai?≤?500) —
the number of bugs per line for each programmer.
Output
Print a single integer — the answer to the problem modulo
mod.
Sample test(s)
Input
3 3 3 100 1 1 1
Output
10
Input
3 6 5 1000000007 1 2 3
Output
0
Input
3 5 6 11 1 2 1
Output
0
题目大意:n个人,一共要写m行程序,每个程序员每行出现的bug数为ai,要求整个程序出现的bug数不超过b的方案数
题目分析:看出来是多重背包就没什么了,dp[i][j]表示前i行出现j个bug的方案数,然后就是背包计数问题
#include <cstdio> #include <cstring> int const MAX = 505; int a[MAX], dp[MAX][MAX]; int main() { int n, m, b, MOD; scanf("%d %d %d %d", &n, &m, &b, &MOD); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); dp[0][0] = 1; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) for(int k = a[i]; k <= b; k++) dp[j][k] = (dp[j][k] + dp[j - 1][k - a[i]]) % MOD; int ans = 0; for(int i = 0; i <= b; i++) ans = (ans + dp[m][i]) % MOD; printf("%d\n", ans); }
D. Destroying Roads
time limit per test:2 seconds
memory limit per test:256 megabytes
In some country there are exactly
n cities and m bidirectional roads connecting the cities. Cities are numbered with integers from
1 to n. If cities
a and b are connected by a road, then in an hour you can go along this road either from city
a to city b, or from city
b to city a. The road network is such that from any city you can get to any other one by moving along the roads.
You want to destroy the largest possible number of roads in the country so that the remaining roads would allow you to get from city
s1 to city
t1 in at most
l1 hours and get from city
s2 to city
t2 in at most
l2 hours.
Determine what maximum number of roads you need to destroy in order to meet the condition of your plan. If it is impossible to reach the desired result, print -1.
Input
The first line contains two integers
n, m (1?≤?n?≤?3000,
) — the number of cities and roads in the country, respectively.
Next m lines contain the descriptions of the roads as pairs of integers
ai,
bi (1?≤?ai,?bi?≤?n,
ai?≠?bi). It is guaranteed that the roads that are given in the description can transport you from any city to any other one. It
is guaranteed that each pair of cities has at most one road between them.
The last two lines contains three integers each,
s1, t1,
l1 and
s2, t2,
l2, respectively (1?≤?si,?ti?≤?n,
0?≤?li?≤?n).
Output
Print a single number — the answer to the problem. If the it is impossible to meet the conditions, print -1.
Sample test(s)
Input
5 4 1 2 2 3 3 4 4 5 1 3 2 3 5 2
Output
0
Input
5 4 1 2 2 3 3 4 4 5 1 3 2 2 4 2
Output
1
Input
5 4 1 2 2 3 3 4 4 5 1 3 2 3 5 1
Output
-1
题目大意:无向图n个点,m条边,要求去掉最多的边使得从s1到t1的时间不超过l1且从s2到t2的时间不超过l2
题目分析:考虑到n的范围又边权固定为1,用bfs求出任意两点间的最短路,然后就是枚举s1到t1和s2到t2路径上的边了(其他不与其相关的边肯定直接被删掉),取最小值即可
#include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std; int const MAX = 3005; vector <int> vt[MAX]; int dis[MAX][MAX]; bool vis[MAX]; int n, m; void BFS() { memset(dis, 0, sizeof(dis)); for(int i = 1; i <= n; i++) { memset(vis, false, sizeof(vis)); queue <int> q; vis[i] = true; q.push(i); while(!q.empty()) { int u = q.front(); q.pop(); int sz = vt[u].size(); for(int j = 0; j < sz; j++) { int v = vt[u][j]; if(!vis[v]) { vis[v] = true; dis[i][v] = dis[i][u] + 1; q.push(v); } } } } } int main() { scanf("%d %d", &n, &m); for(int i = 0; i < m; i++) { int x, y; scanf("%d %d", &x, &y); vt[x].push_back(y); vt[y].push_back(x); } int s1, t1, l1, s2, t2, l2; scanf("%d %d %d %d %d %d", &s1, &t1, &l1, &s2, &t2, &l2); BFS(); if(!(dis[s1][t1] <= l1 && dis[s2][t2] <= l2)) { printf("-1\n"); return 0; } int tmp = dis[s1][t1] + dis[s2][t2]; for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { if(dis[s1][i] + dis[i][j] + dis[j][t1] <= l1 && dis[s2][i] + dis[i][j] + dis[j][t2] <= l2) tmp = min(tmp, dis[s1][i] + dis[i][j] + dis[j][t1] + dis[s2][i] + dis[j][t2]); if(dis[s1][i] + dis[i][j] + dis[j][t1] <= l1 && dis[t2][i] + dis[i][j] + dis[i][s2] <= l2) tmp = min(tmp, dis[s1][i] + dis[i][j] + dis[j][t1] + dis[t2][i] + dis[i][s2]); if(dis[t1][i] + dis[i][j] + dis[j][s1] <= l1 && dis[s2][i] + dis[i][j] + dis[j][t2] <= l2) tmp = min(tmp, dis[t1][i] + dis[i][j] + dis[j][s1] + dis[s2][i] + dis[j][t2]); if(dis[t1][i] + dis[i][j] + dis[j][s1] <= l1 && dis[t2][i] + dis[i][j] + dis[j][s2] <= l2) tmp = min(tmp, dis[t1][i] + dis[i][j] + dis[j][s1] + dis[t2][i] + dis[j][s2]); } printf("%d\n", m - tmp); }