Codeforces989-C. A Mist of Florescence-简单构造*

(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

上图:

这里写图片描述

题目:codeforces round#487:div2 C-传送门

 题面内容及样例在最下面

思路:

 接下来就不用我讲了,看到那张图这还不是个sb题吗?矩阵直接50*50,模拟就行了。

 不过为什么这样可行呢?

因为这样分块之后,每种颜色有25*25的大小。
而每种颜色最多有100个。
每块的每行最多放12个,为了不破坏所属块的连通性
每次要间隔一行放置其他颜色。
所以每个块最多可以放数量12*12的其他颜色而不影响它自己的连通性。
如此,本题就结束了。

闲话:

 如果这个题把颜色改多一点,或者每种颜色的数量更多。
 输出改成如果构造不出这种图案就输出No;反之,输出任一符合条件的图案。

 改成这个样子,应该会更有意思一点吧,嘿嘿。。。

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100+5;
int a,b,c,d;
char mp[N][N];
void paint(int n,int m,char c){
    for(int i=n;i<n+25;++i){
        for(int j=m;j<m+25;++j){
            mp[i][j]=c;
        }
    }
}
int dir[4][2]={1,0,0,1,-1,0,0,-1};
bool ok(int x,int y,char c){
    for(int i=0;i<4;++i){
        int px=x+dir[i][0],py=y+dir[i][1];
        if(px<0||py<0||px>=50||py>=50)continue;
        if(mp[px][py]==c)return false;
    }
    return true;
}
int main(int argc, char const *argv[]){
    while(~scanf("%d%d%d%d",&a,&b,&c,&d)){//题目保证abcd都大于1
        printf("50 50\n");
        paint(0,0,'A');paint(0,25,'B');
        paint(25,0,'C');paint(25,25,'D');
        if(a>1){//暴力处理每个块,其实4处代码本质一样的,复制粘贴了而已
            for(int i=0;i<25&&a>1;i+=2){
                for(int j=25;j<50&&a>1;++j){
                    if(ok(i,j,'A')){
                        mp[i][j]='A';
                        a--;
                    }
                }
            }
        }
        if(b>1){
            for(int i=0;i<25&&b>1;i+=2){
                for(int j=0;j<25&&b>1;++j){
                    if(ok(i,j,'B')){
                        mp[i][j]='B';
                        b--;
                    }
                }
            }
        }
        if(c>1){
            for(int i=25;i<50&&c>1;i+=2){
                for(int j=25;j<50&&c>1;++j){
                    if(ok(i,j,'C')){
                        mp[i][j]='C';
                        c--;
                    }
                }
            }
        }
        if(d>1){
            for(int i=25;i<50&&d>1;i+=2){
                for(int j=0;j<25&&d>1;++j){
                    if(ok(i,j,'D')){
                        mp[i][j]='D';
                        d--;
                    }
                }
            }
        }
        for(int i=0;i<50;++i){
            mp[i][50]='\0';
            printf("%s\n",mp[i] );
        }
    }
    return 0;
}
题面:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

求一个矩阵的逆矩阵:传送门

用代数余子式求逆矩阵方法:

若现有矩阵A,要求其逆矩阵;

若|A|==0,则其不存在逆矩阵;

若|A|!=0,其逆矩阵A^-1==*A/|A|;其中*A为其伴随矩阵;

伴随矩阵的求法:

*A[j][i]==|M[i][j]|,其中M[i][j]为A[i][j]的代数余子式;

即*A1[i][j]==|M[i][j]|,再将*A1转置得到*A;
题解

#include<bits/stdc++.h>
#define MAXN 10
#define MAX 100000000
#define ll long long
using namespace std;

int b[MAXN][MAXN]; //***存储伴随矩阵
//***递归求n*n阶行列式的值
int matrix(int n, int a1[MAXN][MAXN]){
  int b[10][10], sum=0;          //****b保存当前n*n阶行列式a的余子式
  if(n==1) return a1[0][0];     //****n为1时结束递归
  //****通过循环求出当前行列式a[1][0]~a[1][n-1]的所有余子式
  for(int i=0; i<n; i++){
    for(int j=0; j<n-1; j++){
      int column=0;
      for(int k=0; k<n; k++){
        if(k==i) continue;
        b[j][column++]=a1[j+1][k];  //**将a[0][i]的余子式保存到b数组中
      }
    }
    int flag=1;
    if(i&1) flag=-1;
    sum+=flag*a1[0][i]*matrix(n-1, b);
  }
  return sum;
}

//***求矩阵a的伴随矩阵
void adjoint_matrix(int n, int a[MAXN][MAXN]){
  for(int i=0; i<n; i++){
    for(int j=0; j<n; j++){
      int a1[MAXN][MAXN], row=0;
      //****将a[i][j]的余子式存储到a1数组中;
      for(int k=0; k<n; k++){
        int column=0;
        if(k==i) continue;
        for(int l=0; l<n; l++){
          if(l==j) continue;
          a1[row][column++]=a[k][l];  
        }
        row++;
      }
      //****b中存储b[i][j]的算数余子式转置后的矩阵即求得伴随矩阵
      b[j][i]=pow(-1, i+j)*matrix(n-1, a1);  
    }
  }
}

void print(int n, int ans){
  for(int i=0; i<n; i++){
    for(int j=0; j<n; j++){
      if(b[i][j]%ans==0)   {
          cout << b[i][j]/ans << " ";
      }else {
        //******不能整除的话输出最简分式形式
        int cnt=__gcd(b[i][j], ans);
        int x=b[i][j]/cnt, y=ans/cnt;
        if(y<0){
          cout << (-1*x) << "/" << (-1*y) << " ";
        }else{
          cout << x << "/" << y << " ";
        }
        }
    }
    cout << endl;
  }
}

int main(){
  std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  int n;
  while(cin >> n){
    int a[MAXN][MAXN];
    for(int i=0; i<n; i++){
      for(int j=0; j<n; j++){
        cin >> a[i][j];
      }
    }
    int ans=matrix(n, a);
    //*******矩阵值为0即不存在逆矩阵
    if(!ans){
      cout << "The input data is error!" << endl;
      continue;
    }
    adjoint_matrix(n, a);
    print(n, ans);
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值