您的位置:首页 > 其它

Codeforces Round #369 (Div. 2)

2016-08-30 10:16 417 查看
已经变成智障选手了。。。。好久没打比赛的后遗症。。。B题没开long long 被搞成SB。。不爽。。抱了SPS的大腿才上的分,感觉很不好。。。

A.

给一个公交车的座位图,X是有人坐,O是没人坐,问能不能找出一个并排的都没人坐的座位,可以的话就输出YES+答案(可以并排的座位用+号代替O),不行的话就输出NO
样例输入1:

6
OO|OX
XO|XX
OX|OO
XX|OX
OO|OO
OO|XX


样例输出1:

YES
++|OX
XO|XX
OX|OO
XX|OX
OO|OO
OO|XX


样例输入2:

4
XO|OX
XO|XX
OX|OX
XX|OX


样例输出2:

NO


就是暴力题嘛。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
#define LiangJiaJun main
#define LL long long
#define pa pair<int,int>
using namespace std;
char mp[1004][14];
int n;
void print(){
for(int i=1;i<=n;i++){
for(int j=1;j<=5;j++)printf("%c",mp[i][j]);
printf("\n");
}
}
int LiangJiaJun(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%s",mp[i]+1);
for(int i=1;i<=n;i++){
if(mp[i][1]=='O'&&mp[i][2]=='O'){
mp[i][1]=mp[i][2]='+';
printf("YES\n");print();return 0;
}
if(mp[i][4]=='O'&&mp[i][5]=='O'){
mp[i][4]=mp[i][5]='+';
printf("YES\n");print();return 0;
}
}
printf("NO\n");
return 0;
}


B.

给一个残缺的幻方,上面有一个格子是0,求问在这个格子填上其他数字之后,能不能是一个幻方。能的话输出那个数字,不能的话输出-1
PS:填的数字要大于0 。。。

样例输入1:

3
4 0 2
3 5 7
8 1 6


样例输出1:

9


样例输入1:

4
1 1 1 1
1 1 0 1
1 1 2 1
1 1 1 1


样例输出:

-1


被这题坑惨了。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
#define LiangJiaJun main
#define LL long long
#define pa pair<int,int>
using namespace std;
int n;
long long a[504][504],x,y,s,t,q;
int check(){
if(a[x][y]<=0)return 0;

for(int i=1;i<=n;i++){
t=0;
for(int j=1;j<=n;j++)
t+=a[i][j];
if(t!=s){
return 0;
}
}
for(int j=1;j<=n;j++){
t=0;
for(int i=1;i<=n;i++)
t+=a[i][j];
if(t!=s){
return 0;
}
}
t=0;
for(int i=1;i<=n;i++)
t+=a[i][i];
if(t!=s) return 0;
t=0;
for(int i=1;i<=n;i++)
t+=a[i][n-i+1];
if(t!=s) return 0;
return 1;
}
int LiangJiaJun(){
scanf("%d",&n);
if(n==1){
cout<<"1";return 0;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(a[i][j]==0){x=i;y=j;}
for(int i=1;i<=n;i++)
if(i!=x){
for(int j=1;j<=n;j++)
s+=a[i][j];
break;
}
for(int i=1;i<=n;i++)
q+=a[x][i];
a[x][y]=s-q;
if(!check())cout<<"-1"<<endl;
else cout<<a[x][y]<<endl;

return 0;
}


D.

一个数字N,给定数组an,ai表示i到ai有连边,请问有多少种情况给所有的边定向,使得图中没有环。答案对10^9+7取模。

题解:按照给定的图,直接连i到a[i]的单向边,保证有且只有一个环(数据特征)。然后缩环,记下那个环的大小k(即环上的点数),答案就是(2^k-2)*(2^(n-k))

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#define LiangJiaJun main
#define LL long long
#define pa pair<int,int>
#define MOD 1000000007LL
using namespace std;
struct edge{
int to,next;
}e[1000004];
int h[300004],ne=0,cnt=0;
int n,r,p,a[300004],belong[300004],low[300004],dfn[300004],SCC;
int val[300004];
bool inq[300004];
stack<int>ST;
LL temp=0;
LL ans=1;
void insert(int u,int v){
e[++ne].to = v;
e[ne].next = h[u];
h[u] = ne;
}
void tarjan(int x){
inq[x] = 1;
dfn[x] = low[x] = ++cnt;
ST.push(x);
for(int i=h[x];i;i=e[i].next){
if(!dfn[e[i].to]){
tarjan(e[i].to);
low[x] = min(low[x],low[e[i].to]);
}
else if(inq[e[i].to]) low[x] = min(low[x],dfn[e[i].to]);
}
if(low[x] == dfn[x]){
SCC++;int now = -1;
while(now != x){
now = ST.top();ST.pop();
belong[now] = SCC;
inq[now] = 0;
val[SCC]++;
}

}
}

int LiangJiaJun(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
insert(i,x);
}
for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
int rest=n;//cout<<SCC<<endl;
for(int i=1;i<=SCC;i++){
if(val[i]==1)continue;
rest-=val[i];
temp=1;
for(int k=1;k<=val[i];k++)temp=(temp+temp)%MOD;
temp=(temp-2LL+MOD)%MOD;
ans=(ans*temp)%MOD;//cout<<ans<<endl;
}
temp=1;
for(int k=1;k<=rest;k++)temp=(temp+temp)%MOD;
ans=(ans*temp)%MOD;
printf("%I64d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: