usaco 17.Jan 铜组T3

  上午在打usaco月赛的铜组题,T1T2是用来秒杀的,然而T3卡了一上午,下面给出题面:

  题意大概就是输入一个N*N的矩阵,矩阵中元素只有0与1两种状态,每次操作以左上角的点为矩阵中某一矩阵的左上方顶点,将该矩阵中所有元素状态改变(即0变为1,1变为0),求将矩阵中元素全部变为0的最小次数。

  第一次看到样例的时候以为就是一道的DFS或BFS的搜索题,然后果断写了DFS,很正常就WA了。然而其实这道题需要用到贪心。。。

  题目中提到,一个矩阵被改变两次之后还是原先的状态,那既然这样,如果将右下角的点留到最后处理的话,有很大可能会重复某次操作,所以每次操作的右下角顶点应该是从右下角开始搜索的,既然这样,每次操作的矩阵应该怎样选取呢?

  因为最后要把所有的元素都变为0,那么最优解其实就是保证每次操作的右下角顶点都为1,并且保证该矩阵中所含1的个数最多。

  那么这样的话策略就已经有了。代码如下: 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<string>
 5 #include<cstring>
 6 using namespace std;
 7 int sum[11][11],n,ans=0;
 8 char a[11][11];
 9 string s[11];
10 bool f[11][11];
11 int main()
12 {
13     freopen("cowtip.in","r",stdin);
14     freopen("cowtip.out","w",stdout);
15     cin>>n;
16     for (int i=1;i<=n;i++)
17         cin>>s[i];
18     for (int i=1;i<=n;i++)
19         for (int j=0;j<n;j++)
20         {
21             a[i][j+1]=s[i][j];
22             f[i][j]=true;
23             sum[i][j+1]=sum[i-1][j+1]+sum[i][j]-sum[i-1][j]+a[i][j+1]-'0';
24         }
25     for (;;)
26     {
27         bool flag=false;
28         for (int i=1;i<=n;i++)
29         {
30             for (int j=1;j<=n;j++)
31                 if (a[i][j]=='1'){flag=true;    break;}    
32             if (flag)    break;
33         }
34         if (!flag)    break;//判断矩阵是否全部为0
35         ans++;
36         int maxx=0,x=0,y=0;
37         for (int i=1;i<=n;i++)
38             for (int j=1;j<=n;j++)
39                 if (sum[i][j]>maxx&&a[i][j]=='1')//查找右下点状态为1且包含状态为1的元素的个数最多的矩阵的右下点
40                 {
41                     maxx=sum[i][j];
42                     x=i;    y=j;
43                 }
44         for (int i=1;i<=x;i++)
45         {
46             for (int j=1;j<=y;j++)
47                 {
48                     if (a[i][j]=='1')    a[i][j]='0';
49                     else    a[i][j]='1';//将所选取矩阵中所有元素的状态改变
50                 }
51         }
52         for (int i=1;i<=n;i++)
53             for (int j=1;j<=n;j++)
54                 sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j]-'0';//数据改变后再求矩阵前缀和
55     }
56     cout<<ans<<endl;
57     return 0;
58 }
AC代码

 

转载于:https://www.cnblogs.com/hinanawitenshi/p/6286816.html

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值