Codeforces Round #302 (Div. 2) (ABCD题解)

来源:互联网 发布:mac怎么安装steam 编辑:程序博客网 时间:2024/05/18 00:41

比赛链接: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 ofk strings s1, s2, ..., sk is calledbeautiful, if the concatenation of these strings is stringq (formally, s1 + s2 + ... + sk = q) and the first characters of these strings are distinct.

Find any beautiful sequence of strings or determine that thebeautiful sequence doesn't exist.

Input

The first line contains a positive integer k (1 ≤ k ≤ 26) — the number of strings that should be in abeautiful sequence.

The second line contains string q, consisting of lowercase Latin letters. The length of the string is within range from1 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 nextk lines print the beautiful sequence of strings s1, s2, ..., sk.

If there are multiple possible answers, print any of them.

Sample test(s)
Input
1abca
Output
YESabca
Input
2aaacas
Output
YESaaacas
Input
4abc
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 ofn 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 exactlyk islands appear on the map. We will call a set of sand cells to beisland 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 exactlyk 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 nextn 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 equaln.

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
YESSSSSSLLLLLSSSSSLLLLLSSSSS
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 exactlym lines of code. There are n programmers working on a project, the i-th of them makes exactlyai bugs in every line of code that he writes.

Let's call a sequence of non-negative integers v1, v2, ..., vn aplan, 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 writesv2 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 plangood, if all the written lines of the task contain at mostb 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 integermod.

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 integersa1, a2, ..., an (0 ≤ ai ≤ 500) — the number of bugs per line for each programmer.

Output

Print a single integer — the answer to the problem modulomod.

Sample test(s)
Input
3 3 3 1001 1 1
Output
10
Input
3 6 5 10000000071 2 3
Output
0
Input
3 5 6 111 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 from1 to n. If citiesa and b are connected by a road, then in an hour you can go along this road either from citya to city b, or from cityb 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 citys1 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 integersai,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 41 22 33 44 51 3 23 5 2
Output
0
Input
5 41 22 33 44 51 3 22 4 2
Output
1
Input
5 41 22 33 44 51 3 23 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);}

1 0