全场wa longlong 无颜见江东父老
a题
找两个连着的O变成+
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n;
char s[1010][5];
void init(){
scanf("%d",&n);
int flag = 0;
for(int i = 0 ; i < n ;i++){
scanf("%s",s[i]);
// printf("%s\n",s[i]);
if(s[i][0] == 'O' &&s[i][1] == 'O'&&flag == 0)
s[i][0] = '+',s[i][1] = '+',flag = 1;
else if(s[i][3] == 'O' &&s[i][4] == 'O'&&flag == 0)
s[i][3] = '+',s[i][4] = '+',flag = 1;
}
if(flag){
printf("YES\n");
for(int i = 0 ; i < n;i++){
for(int j = 0 ; j < 5 ;j++)
printf("%c",s[i][j]);
printf("\n");
}
}
else{
printf("NO\n");
}
}
int main(){
init();
}
b题:
把0的位置填数字,使得每行没列主对角线和副对角线的和都相同,做不到输出-1
wa点:
首先wa4 如果只有一个数字,不是0的话就不变,是零输出1或者随便什么数字
wa7 这个数字0 wa94 这个数字<0
血粼粼的教训
我是用行判断ans,填数字,在判断填入后列和对角线的条件是否符合
#include<cstdio>
#include <iostream>
#include <cstring>
#define maxn 520
using namespace std;
int n,anr,anl;
long long r[maxn],l,flag,ans;
long long a[maxn][maxn];
int init(){
for(int i = 0 ; i < n ;i++){
flag = 0;
for(int j = 0 ; j < n ;j++){
scanf("%I64d",&a[i][j]);
if(a[i][j] == 0)
anr = i,anl = j,flag = 1;
r[i]+=a[i][j];
}
if(flag == 0&&ans == 0)
ans = r[i];
if(ans != 0 && ans != r[i]&&flag == 0)
return -1;
}
}
void sov(){
a[anr][anl] = ans-r[anr];
for(int j = 0 ; j < n ;j++){
l = 0;
for(int i = 0 ; i < n ;i++){
l += a[i][j];
}
if(l != ans){
printf("-1\n");
return;
}
}
long long lp = 0;
for(int i = 0 ; i < n ; i++){
lp += a[i][i];
// cout << lp <<endl;
}
if(lp != ans){
printf("-1\n");
return;
}
lp = 0;
for(int i = 0 ; i < n ;i++)
lp += a[i][n-1-i];
if(lp != ans){
printf("-1\n");
return ;
}
if(a[anr][anl]>0)
printf("%I64d\n",a[anr][anl]);
else
printf("-1\n");
}
int main(){
scanf("%d",&n);
if(n == 1){
int aa = 0;
scanf("%d",&aa);
if(aa == 0)
printf("1\n");
else
printf("%d\n",aa);
}
else{
if(init() == -1)
printf("-1\n");
else
sov();
}
}
c题:
比赛的时候就剩下20分钟,看了一眼,直接无脑开三维(最后一维可以滚动,没时间改了),dp【i】【j】【k】表示当前第 i 课树,涂第 j 种颜色,已经分了 k 块颜色,要知道k只可能是前一个棵树的k或者+1,不解释了,转移要分一下,这棵树如果有颜色就不存在j了,直接给corlor【i】,else 和前一棵树颜色一样与否,循环前一棵树的第二帷 ,O(n^4),有点暴力哈
#include <cstdio>
#include <iostream>
#define maxn 110
using namespace std;
int n,m,k;
long long dp[maxn][maxn][maxn],a[maxn][maxn],cl[maxn];
void init(){
scanf("%d%d%d",&n,&m,&k);
for(int i = 1 ; i <= n ;i++)
scanf("%I64d",&cl[i]);
for(int i = 1 ; i <= n ;i++)
for(int j = 1; j <= m ;j++)
scanf("%I64d",&a[i][j]);
for(int i = 0 ; i <= n ; i++)
for(int j = 0 ; j <= m ; j++)
for(int l = 0 ; l <= k ;l++)
dp[i][j][l] = 1e15;
for(int i = 0 ; i <= m ;i++){
if(k == 1)
dp[0][i][1] = 0;
dp[0][i][0] = 0;
}
}
void sov(){
for(int i = 1 ; i <= n ;i++){
for(int j = 1 ; j <= m ;j++){
for(int nn = 1 ;nn <= k ;nn++){
if(cl[i] != 0)
for(int jj =1; jj <= m ;jj++)
if(jj != cl[i])
dp[i][cl[i]][nn] = min(dp[i][cl[i]][nn],dp[i-1][jj][nn-1]);
else
dp[i][cl[i]][nn] = min(dp[i-1][jj][nn],dp[i][cl[i]][nn]);
else{
for(int jj =1 ; jj <= m ;jj++)
if(jj != j)
dp[i][j][nn] = min(dp[i][j][nn],dp[i-1][jj][nn-1]+a[i][j]);
else{
dp[i][j][nn] = min(dp[i][j][nn],dp[i-1][jj][nn]+a[i][j]);
// printf("dp [ %d ] [ %d ] [ %d ] = %d \n",i,j,nn,dp[i][j][nn]);
}
}
}
}
}
// cout << dp[1][1][1]<<endl;
long long ans = 1e15;
for(int i = 1 ; i <= m ;i++){
ans = min(ans,dp[n][i][k]);
//cout << n <<i << k <<dp[n][i][k] <<endl;
}
if(ans >= 1e15)
printf("-1\n");
else
printf("%I64d\n",ans);
}
int main(){
init();
sov();
}
D题:
每个点只有唯一出度,连向另一个点(连自己特判),改变任意条边的方向,使得整个图没有环
因为唯一出度,所以只要你沿着一条线走,如果没遇到某个点,那么这两个点必然不可能在一个环里,环里的随便翻 除了都反转或者都不 就是2^n-2种 外面的随便,剩下多少点就2^n,所以的相乘。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#define maxn 200010
const int mod= 1e9+7;
using namespace std;
vector<int> vc[maxn];
bool vis[maxn],v[maxn];
int n,m,cir,r[maxn],num;
long long ans =1;
int init(){
scanf("%d",&n);
for(int i = 1 ; i <= n ;i++){
int to;
scanf("%d",&to);
vc[i].push_back(to);
if(to == i)
return -1;
}
}
long long po(int x){
long long an = 1;
for(int i = 0 ; i < x ;i++)
an = (an*2)%mod;
return an;
}
int s;
int dfs(int x,int step){
if(v[x]){
cir++;
// cout <<" "<<step-r[x]<<endl;
return step-r[x];
}
if(vis[x])
return 0;
r[x] = step;
vis[x] =1;
v[x] = 1;
for(int i = 0 ; i <vc[x].size();i++){
s = dfs(vc[x][i],step+1);
}
return s;
}
int main(){
// cout << "ans = "<<ans<<endl;
if(init() == -1)
printf("0\n");
else{
for(int i = 1; i <= n ;i++){
if(!vis[i]){
memset(v,0,sizeof(v));
m = dfs(i,0);
if(m)
ans = (ans*(po(m)-2))%mod;
num += m;
}
}
ans = (ans*po(n-num)) %mod;
printf("%d\n",ans);
}
}