zoukankan      html  css  js  c++  java
  • poj 3185 The Water Bowls

    The Water Bowls

     POJ - 3185 

    一个由20个数字(0或1)组成的数列,问最少操作多少次能将其变成一个全0数列,每次操作可以选择一个数字,将其左边右边和本身翻转

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int a[22],b[22],ans1,ans2;
    int main(){
        for(int i=1;i<=20;i++)scanf("%d",&a[i]),b[i]=a[i];
        for(int i=2;i<=20;i++){
            if(a[i-1]==1){
                a[i-1]^=1;
                a[i]^=1;
                a[i+1]^=1;
                ans1++;
            }
        }
        for(int i=19;i>=1;i--){
            if(b[i+1]==1){
                b[i+1]^=1;
                b[i]^=1;
                b[i-1]^=1;
                ans2++;
            }
        }
        printf("%d",min(ans1,ans2));
        return 0;
    }
    100分 贪心(从左到右或从右到左)
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define INF 0x3fffffff
    #define maxn 20
    using namespace std;
    int a[22][22],x[22],free_n;
    int gcd(int a,int b){
        if(a<0)return gcd(-a,b);
        if(b<0)return gcd(a,-b);
        return b==0?a:gcd(b,a%b);
    }
    int guass(){
        int k,col=0;
        for(k=0;k<20&&col<20;k++,col++){
            int mx=k;
            for(int i=k+1;i<20;i++)
                if(a[i][col]>a[mx][col])mx=i;
            for(int i=k;i<21;i++)swap(a[k][i],a[mx][i]);
            if(!a[k][col]){k--;continue;}//不太明白为什么要k-- 
            for(int i=k+1;i<20;i++){//这个循环都不明白 
                if(a[i][col]!=0){
                    int lcm=a[k][col]/gcd(a[k][col],a[i][col])*a[i][col];
                    int ta=lcm/a[i][col],tb=lcm/a[k][col];
                    if(a[i][col]*a[k][col]<0)tb=-tb;
                    for(int j=col;j<21;j++)
                        a[i][j]=((a[i][j]*ta)%2-(a[k][j]*tb)%2+2)%2;
                }
            }
        }
        for(int i=0,j;i<20;i++){
            if(!a[i][i]){
                for(j=i+1;j<20;j++)
                    if(a[i][j])break;
                if(j==20)break;
                for(int r=0;r<20;r++)swap(a[r][i],a[r][j]);
            }
        }
        int mn=INF;
        for(int j=0;j<(1<<(20-k));j++){
            for(int i=0;i<(20-k);i++)
                if(j&(1<<i))x[20-1-i]=1;
                else x[20-1-i]=0;
            for(int i=k-1;i>=0;i--){
                int tmp=a[i][20]%2;
                for(int j=i+1;j<20;j++)
                    if(a[i][j])tmp=(tmp-a[i][j]*x[j]%2+2)%2;
                x[i]=(tmp/a[i][i])%2;
            }
            int tmp=0;
            for(int i=0;i<20;i++)tmp+=x[i];
            mn=min(mn,tmp);
            if(mn==0)break;
        }
        return mn;
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        for(int i=0;i<20;i++){//枚举对每个数字进行操作 
            scanf("%d",&a[i][20]);
            a[i][i]=1;
            if(i>0)a[i-1][i]=1;
            if(i<19)a[i+1][i]=1;
        }
        printf("%d",guass());
    }
    100分 高斯消元+枚举变元
  • 相关阅读:
    java语言基础001
    Linux 使用硬盘
    Linux 系统运行命令 > 查看系统信息
    Linux rm 命令
    Linux 操作系统目录结构
    JavaScript || 事件基础
    My SQL随记 003 数据表基础操作语法
    My SQL随记 002 登陆
    My SQL随记 001 常用名词/结构化语言
    linux命令学习
  • 原文地址:https://www.cnblogs.com/thmyl/p/8085775.html
Copyright © 2011-2022 走看看