比赛链接:http://codeforces.com/contest/508
A. Pasha and Pixels
Pasha loves his phone and also putting his hair up... But the hair is now irrelevant.
Pasha has installed a new game to his phone. The goal of the game is following. There is a rectangular field consisting ofn row withm pixels in each row. Initially, all the pixels are colored white. In one move, Pasha can choose any pixel and color it black. In particular, he can choose the pixel that is already black, then after the boy's move the pixel does not change, that is, it remains black. Pasha loses the game when a2 × 2 square consisting of black pixels is formed.
Pasha has made a plan of k moves, according to which he will paint pixels. Each turn in his plan is represented as a pair of numbersi andj, denoting respectively the row and the column of the pixel to be colored on the current move.
Determine whether Pasha loses if he acts in accordance with his plan, and if he does, on what move the2 × 2 square consisting of black pixels is formed.
The first line of the input contains three integersn, m, k (1 ≤ n, m ≤ 1000,1 ≤ k ≤ 105) — the number of rows, the number of columns and the number of moves that Pasha is going to perform.
The next k lines contain Pasha's moves in the order he makes them. Each line contains two integersi andj (1 ≤ i ≤ n,1 ≤ j ≤ m), representing the row number and column number of the pixel that was painted during a move.
If Pasha loses, print the number of the move when the2 × 2 square consisting of black pixels is formed.
If Pasha doesn't lose, that is, no 2 × 2 square consisting of black pixels is formed during the given k moves, print 0.
2 2 4
1 1
1 2
2 1
2 2
4
2 3 6
2 3
2 2
1 3
2 2
1 2
1 1
5
5 3 7
2 3
1 2
1 1
4 1
3 1
5 3
3 2
0
题目大意:n行m列k个坐标,当出现一个1*1的小正方形时输出当前坐标个数(因为是像素块,这里不用考虑斜着的情况)
题目分析:水,模拟
#include <cstdio>
#include <cstring>
int map[1005][1005];
int main()
{
int n, m, k, ans = 0;
memset(map, 0, sizeof(map));
scanf("%d %d %d", &n, &m, &k);
for(int i = 1; i <= k; i++)
{
int x, y;
scanf("%d %d", &x, &y);
map[x][y] = 1;
if(!ans)
{
if(map[x][y + 1] && map[x + 1][y] && map[x + 1][y + 1])
ans = i;
else if(map[x - 1][y] && map[x][y + 1] && map[x - 1][y + 1])
ans = i;
else if(map[x][y - 1] && map[x + 1][y] && map[x + 1][y - 1])
ans = i;
else if(map[x][y - 1] && map[x - 1][y] && map[x - 1][y - 1])
ans = i;
}
else
break;
}
printf("%d\n", ans);
}
Berland, 2016. The exchange rate of currency you all know against the burle has increased so much that to simplify the calculations, its fractional part was neglected and the exchange rate is now assumed to be an integer.
Reliable sources have informed the financier Anton of some information about the exchange rate ofcurrency you all know against the burle for tomorrow. Now Anton knows that tomorrow the exchange rate will be an even number, which can be obtained from the present rate by swapping exactly two distinct digits in it. Of all the possible values that meet these conditions, the exchange rate for tomorrow will be the maximum possible. It is guaranteed that today the exchange rate is anodd positive integern. Help Anton to determine the exchange rate ofcurrency you all know for tomorrow!
The first line contains an odd positive integer n — the exchange rate of currency you all know for today. The length of numbern's representation is within range from2 to105, inclusive. The representation ofn doesn't contain any leading zeroes.
If the information about tomorrow's exchange rate is inconsistent, that is, there is no integer that meets the condition, print - 1.
Otherwise, print the exchange rate of currency you all know against the burle for tomorrow. This should be the maximum possible number of those that are even and that are obtained from today's exchange rate by swapping exactly two digits. Exchange rate representation should not contain leading zeroes.
527
572
4573
3574
1357997531
-1
题目大意:给一个奇数,交换任意两个得到一个最大的偶数,只能交换一次,不存在输出-1
题目分析:从低位往高位先找一个偶数,找不到则输出-1,然后找小于第一位的偶数,找到则与第一位交换
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char s[100005];
int main()
{
scanf("%s", s);
int l = strlen(s) - 1;
int tmp = -1;
for(int i = l; i >= 0; i--)
if(s[i] % 2 == 0)
if(s[i] < s[l] || tmp == -1)
tmp = i;
if(tmp == -1)
printf("-1\n");
else
{
swap(s[tmp], s[l]);
printf("%s\n", s);
}
}
Anya loves to watch horror movies. In the best traditions of horror, she will be visited bym ghosts tonight. Anya has lots of candles prepared for the visits, each candle can produce light for exactlyt seconds. It takes the girl one second to light one candle. More formally, Anya can spend one second to light one candle, then this candle burns for exactlyt seconds and then goes out and can no longer be used.
For each of the m ghosts Anya knows the time at which it comes: thei-th visit will happenwi seconds after midnight, allwi's are distinct. Each visit lasts exactly one second.
What is the minimum number of candles Anya should use so that during each visit, at leastr candles are burning? Anya can start to light a candle at any time that is integer number of seconds from midnight, possibly, at the time before midnight.That means, she can start to light a candle integer number of seconds before midnight or integer number of seconds after a midnight, or in other words in any integer moment of time.
The first line contains three integers m, t, r (1 ≤ m, t, r ≤ 300), representing the number of ghosts to visit Anya, the duration of a candle's burning and the minimum number of candles that should burn during each visit.
The next line contains m space-separated numberswi (1 ≤ i ≤ m,1 ≤ wi ≤ 300), thei-th of them repesents at what second after the midnight thei-th ghost will come. Allwi's are distinct, they follow in the strictly increasing order.
If it is possible to make at least r candles burn during each visit, then print the minimum number of candles that Anya needs to light for that.
If that is impossible, print - 1.
1 8 3
10
3
2 10 1
5 8
1
1 1 3
10
-1
Anya can start lighting a candle in the same second with ghost visit. But this candle isn't counted as burning at this visit.
It takes exactly one second to light up a candle and only after that second this candle is considered burning; it means that if Anya starts lighting candle at moment x, candle is buring from second x + 1 to second x + t inclusively.
In the first sample test three candles are enough. For example, Anya can start lighting them at the3-rd,5-th and7-th seconds after the midnight.
In the second sample test one candle is enough. For example, Anya can start lighting it one second before the midnight.
In the third sample test the answer is - 1, since during each second at most one candle can burn but Anya needs three candles to light up the room at the moment when the ghost comes.
题目大意:一个人要遇到m只鬼,遇到每只鬼要的时间为w[i],他的蜡烛能亮t秒,遇到一只鬼要至少有r支蜡烛亮着,他点燃蜡烛要1s,点燃的时间不算燃烧的时间,求他最少要带多少根蜡烛,要不存在解输出-1
题目分析:按区间模拟,首先要判断的是当t小于r时无解,因为点燃也要1s,因此不可能存在一个时刻让r支蜡烛都亮着,接着我们先找遇到第一个鬼的前1秒点一支蜡烛,假设此时为时刻t0则其后t0 + 1 + t的时间这根蜡烛都亮着,则这段区间标记一下,若此时不足以过第一个鬼则再遇到其前的第2秒再点一根,依次前推,注意当t0 + 1 + i小于0时,时间为负,不计积累量
#include <cstdio>
#include <cstring>
int const MAX = 1e4 + 5;
int w[MAX], vis[MAX];
int main()
{
int m, t, r, ans = 0;
scanf("%d %d %d", &m, &t, &r);
if(t < r)
{
printf("-1\n");
return 0;
}
memset(vis, 0, sizeof(vis));
for(int i = 0; i < m; i++)
scanf("%d", &w[i]);
for(int i = 0; i < m; i++)
{
for(int j = w[i] - 1; vis[w[i]] < r; j--)
{
for(int k = j + 1; k <= j + t; k++)
if(k >= 0)
vis[k]++;
ans++;
}
}
printf("%d\n", ans);
}
While dad was at work, a little girl Tanya decided to play with dad's password to his secret database. Dad's password is a string consisting ofn + 2 characters. She has written all the possiblen three-letter continuous substrings of the password on pieces of paper, one for each piece of paper, and threw the password out. Each three-letter substring was written the number of times it occurred in the password. Thus, Tanya ended up withn pieces of paper.
Then Tanya realized that dad will be upset to learn about her game and decided to restore the password or at least any string corresponding to the final set of three-letter strings. You have to help her in this difficult task. We know that dad's password consisted of lowercase and uppercase letters of the Latin alphabet and digits. Uppercase and lowercase letters of the Latin alphabet are considered distinct.
The first line contains integer n (1 ≤ n ≤ 2·105), the number of three-letter substrings Tanya got.
Next n lines contain three letters each, forming the substring of dad's password. Each character in the input is a lowercase or uppercase Latin letter or a digit.
If Tanya made a mistake somewhere during the game and the strings that correspond to the given set of substrings don't exist, print "NO".
If it is possible to restore the string that corresponds to given set of substrings, print "YES", and then print any suitable password option.
5 aca aba aba cab bac
YES abacaba
4 abc bCb cb1 b13
NO
7 aaa aaa aaa aaa aaa aaa aaa
YES aaaaaaaaa
题目大意:给一个n,输入n个长度为3的字符串,字符包含英文的大小写和数字,判断是否存在一个长度为n+2的字符串包含全部n个子串
题目分析:可以把问题转化为判断是否存在欧拉通路,那如何构图?因为题目说了每个字符串的长度为3,因此我们把它的前两个字符当做一个结点,后两个字符当作一个结点,然后构建一个有向图,只需要判断这张图是否存在欧拉通路即可,欧拉通路是一条经过图(无向图或有向图)中所有边一次且仅一次行遍图中所有顶点的通路。这题和poj2377有点类似,但是这题有两点比那题棘手,1是结点的存储问题,那题是尾首字符相同便可链接,而这题需要将结点散列,因为一共就10+26+26=62个字符,我们先将62个字符从1到61编号再把结点设置为62x+y的整型变量,则可以将所有结点表示出来。还有个麻烦的地方在于数据量,本题的n即边数达到20w,如果已经判断存在欧拉通路,按照点dfs来找的话,平行边和自环一多很有可能超时甚至爆栈,因此我们可以用边来找,用边找的好处是找的过程中可以把自环和平行的都去掉,下面就是如何判断是否存在欧拉通路的问题,这里简单说,(我有详细介绍此类问题的博文)
1.并查集判连通
2.出入度都相等则为欧拉回路,dfs起点任意,若出入度相差1的点的个数不大于2则把出度大的做为起点,若个数大于2或者出入度相差超多1则不存在欧拉通路
#include <cstdio>
#include <cstring>
int const MAX = 200005;
int const MAX2 = 4000;
bool has[MAX2];
int fa[MAX2], out[MAX2], in[MAX2], path[MAX], e[MAX2][MAX2];
int n, len, st;
struct node
{
int u, v;
char name[3];
}r[MAX];
int abs(int x)
{
return x > 0 ? x : -x;
}
void UF_set()
{
for(int i = 0; i < MAX2; i++)
fa[i] = i;
}
int Find(int x)
{
return x == fa[x] ? x : fa[x] = Find(fa[x]);
}
void Union(int a, int b)
{
int r1 = Find(a);
int r2 = Find(b);
if(r1 != r2)
fa[r1] = r2;
}
int ctoi(char ch)
{
if(ch >= 'A' && ch <= 'Z') return ch - 'A' + 10;
if(ch >= 'a' && ch <= 'z') return ch - 'a' + 36;
return ch - '0';
}
char itoc(int a)
{
if(a >= 0 && a <= 9) return '0' + a;
if(a >= 10 && a <= 35) return 'A' + a - 10;
return 'a' + a - 36;
}
bool Exist()
{
int t = -1;
for(int i = 0; i < MAX2; i++)
{
if(has[i])
{
if(t == -1)
t = Find(i);
else if(Find(i) != t)
return false;
}
}
int sum = 0, tmp;
for(int i = 0; i < MAX2; i++)
{
if(has[i])
{
tmp = i;
if(in[i] != out[i])
{
sum++;
if(abs(in[i] - out[i]) > 1)
return false;
if(out[i] > in[i])
st = i;
}
}
}
if(sum > 2)
return false;
if(sum == 0)
st = tmp;
return true;
}
void DFS(int now)
{
for(int i = 0; i < MAX2; i++)
{
while(e[now][i])
{
e[now][i]--;
DFS(i);
path[len++] = i;
}
}
}
int main()
{
scanf("%d", &n);
UF_set();
memset(e, 0, sizeof(e));
for(int i = 0; i < n; i++)
{
scanf("%s", r[i].name);
r[i].u = ctoi(r[i].name[0]) * 62 + ctoi(r[i].name[1]);
r[i].v = ctoi(r[i].name[1]) * 62 + ctoi(r[i].name[2]);
has[r[i].u] = true;
has[r[i].v] = true;
Union(r[i].u, r[i].v);
out[r[i].u]++;
in[r[i].v]++;
e[r[i].u][r[i].v]++;
}
if(!Exist())
printf("NO\n");
else
{
len = 0;
DFS(st);
path[len++] = st;
printf("YES\n");
printf("%c%c", itoc(path[len - 1] / 62), itoc(path[len - 1] % 62));
for(int i = len - 2; i >= 0; i--)
printf("%c", itoc(path[i] % 62));
printf("\n");
}
}
Notice that the memory limit is non-standard.
Recently Arthur and Sasha have studied correct bracket sequences. Arthur understood this topic perfectly and become so amazed about correct bracket sequences, so he even got himself a favorite correct bracket sequence of length2n. Unlike Arthur, Sasha understood the topic very badly, and broke Arthur's favorite correct bracket sequence just to spite him.
All Arthur remembers about his favorite sequence is for each opening parenthesis ('(') the approximate distance to the corresponding closing one (')'). For the i-th opening bracket he remembers the segment[li, ri], containing the distance to the corresponding closing bracket.
Formally speaking, for the i-th opening bracket (in order from left to right) we know that the difference of its position and the position of the corresponding closing bracket belongs to the segment[li, ri].
Help Arthur restore his favorite correct bracket sequence!
The first line contains integer n (1 ≤ n ≤ 600), the number of opening brackets in Arthur's favorite correct bracket sequence.
Next n lines contain numbersli andri (1 ≤ li ≤ ri < 2n), representing the segment where lies the distance from thei-th opening bracket and the corresponding closing one.
The descriptions of the segments are given in the order in which the opening brackets occur in Arthur's favorite sequence if we list them from left to right.
If it is possible to restore the correct bracket sequence by the given data, print any possible choice.
If Arthur got something wrong, and there are no sequences corresponding to the given information, print a single line "IMPOSSIBLE" (without the quotes).
4
1 1
1 1
1 1
1 1
()()()()
3
5 5
3 3
1 1
((()))
3
5 5
3 3
2 2
IMPOSSIBLE
3
2 3
1 4
1 4
(())()
题目大意:给出n组区间,每组区间为第i个括号的左右半边的下标值的相差范围,问存不存在这样的满足限制的括号序列,存在则输出,不存在输出IMPOSSIBLE
题目分析:本题可用dfs搜出来,但分析后存在更简单的方法,即选择栈来操作序列,理由是类似((())),(()()())这种类型的括号序列,我们可以很清楚的发现它们满足后进先出的特点,即遇到相匹配的则出栈,在对栈操作过程中我们总是选择栈顶的“(”来和“)”匹配,因为要满足题意我们可以根据所给区间的范围来选择合适的进出栈顺序,选择方式如下:
先将"("进栈,记录栈中"("的个数
1.当前字符串长+1大于等于当前栈内元素个数+当前区间左端点值,相等时就是遇到一组匹配的"()"
2.若1且当前字符串长+1小于等于当前栈内元素个数+当前区间右端点值,
3.若2则栈顶“(”出栈,若不满足2则直接输出IMPOSSIBLE退出,因为此时找不到与之匹配的")",相当于无解
条件2很好理解因为给了一个区间,设"("的下标为l,与之匹配的")"下标为r,则有l = stack.size(),r∈[l+l0,l+r0]
最后若栈内还有元素则表示存在找不到匹配的"(",则输出IMPOSSIBLE
#include <cstdio>
#include <cstring>
#include <stack>
#include <string>
#include <iostream>
using namespace std;
int const MAX = 605;
int l[MAX], r[MAX], num[MAX];
stack<int> st;
string s;
int main()
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d %d", &l[i], &r[i]);
for(int i = 0; i < n; i++)
{
s.push_back('(');
st.push(i);
num[i] = s.size();
while(!st.empty() && (num[st.top()] + l[st.top()] <= s.size() + 1))
{
if(num[st.top()] + r[st.top()] >= s.size() + 1)
{
s.push_back(')');
st.pop();
}
else
{
printf("IMPOSSIBLE\n");
return 0;
}
}
}
if(st.empty())
cout << s << endl;
else
printf("IMPOSSIBLE\n");
}