http://codeforces.com/contest/688/
A题
大水题,注意考虑特殊情况;
B题
题目大意:找出第n个位数是偶数的回文数, n (1 ≤ n ≤ 10100 000).
没有什么很厉害的方法,其实就是一道找规律题。把前几个写出来就知道了。
所以解法就是输出字符串n和n的反转。
c题
题目大意:某集合的性质为其中的元素都是图中任意一边的顶点,求两个这样的集合,如果不存在,则输出-1.
源码:
<span style="white-space:pre"> </span><pre name="code" class="cpp">#include <stdio.h>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
int n,m;
vector<int> map[100005];
int color[100005];
bool mark[100005];
int black[100005];
int white[100005];
int B,W;
void init(){
for(int i = 1;i<=m;i++){
color[i] = 0;
mark[i] = false;
}
}
bool search(){
queue<int> q;
q.push(1);
int head;
int col = 1;
if(!map[1].empty()){
color[1] = col;
B++;
black[0] = 1;
mark[1] = true;
}
while(!q.empty()){
head = q.front();
int a;
if(!map[head].empty()){
for(int i=0;i<map[head].size();i++){
a = map[head][i];
if(mark[a]){
if(color[a]==color[head]){
return false;
}
}
else{
color[a] = -1*color[head];
if(color[a]==1){
B++;
black[B-1] = a;
}
else{
W++;
white[W-1] = a;
}
mark[a] = true;
q.push(a);
}
}
}
q.pop();
if(q.empty()){
for(int i = 2;i<=n;i++){
if(!mark[i]&&!map[i].empty()){
// printf("%d",i);
q.push(i);
mark[i] = true;
color[i] = 1;
B++;
black[B-1] = i;
break;
}
}
}
}
return true;
}
int main(){
scanf("%d%d",&n,&m);
int u,v;
init();
for(int i = 0;i<m;i++){
scanf("%d%d",&u,&v);
map[u].push_back(v);
map[v].push_back(u);
}
if(!search())
printf("-1\n");
else{
sort(black,black+B);
sort(white,white+W);
if(B<W){
printf("%d\n",B);
printf("%d",black[0]);
for(int i = 1;i<B;i++)
printf(" %d",black[i]);
printf("\n");
printf("%d\n",W);
printf("%d",white[0]);
for(int i = 1;i<W;i++)
printf(" %d",white[i]);
}
else{
printf("%d\n",W);
printf("%d",white[0]);
for(int i = 1;i<W;i++)
printf(" %d",white[i]);
printf("\n");
printf("%d\n",B);
printf("%d",black[0]);
for(int i = 1;i<B;i++)
printf(" %d",black[i]);
}
/*
for(int i = 1;i<=n;i++){
printf("%d ",color[i]);*/
}
return 0;
}
感觉最后输出判断没什么用的样子。。
算法思想就是广搜,每搜到一个点就染成和它父亲相反的颜色。如果这个点也是其他结点的儿子,则判断其当前颜色是否与将染的颜色相反。
注意要搜到所有的点。
wa的原因:
1.设置了无用的col变量,后来发现直接用父节点颜色就好了。
2.无向图要双!向!存!