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

### USACO 2025 February Contest Bronze Division Problems and Solutions #### Problem Overview The United States of America Computing Olympiad (USACO) holds contests four times a year, including the February contest. For the Bronze division, participants face algorithmic challenges designed to test basic programming skills and problem-solving abilities. Since specific details about the exact problems from the USACO 2025 February Contest are not available yet, one can infer based on previous years&#39; patterns what types of questions might appear[^1]. Typically, these include tasks involving simple algorithms like sorting, searching, or handling strings and arrays efficiently. For instance, past contests have featured games between characters such as Bessie playing with palindromes where players take turns removing stones equal to palindrome numbers until no more moves remain[^2]. Another common type involves optimizing certain conditions over circular structures which require careful consideration when iterating through elements due to wrap-around properties[^3]. Given this context, let&#39;s consider an example similar to those seen before: #### Example Problem: Palindrome Game Simulation In a game played by two individuals named Bessie and her friend, they start with a pile containing some number of pebbles. Players alternate taking away any positive integer amount of rocks that forms a palindrome sequence during their turn. The player who removes all remaining items wins the match. Given multiple starting configurations represented by `T` different scenarios, determine whether Bessie has winning strategy assuming optimal play from both sides. To solve this kind of challenge programmatically, dynamic programming techniques could prove useful alongside checking for possible valid moves at each step while keeping track of previously encountered states to avoid redundant calculations. ```cpp #include <iostream> using namespace std; bool is_palindrome(int num){ string s = to_string(num); int l=0,h=s.size()-1; while(l<h && s[l]==s[h]) { ++l; --h; } return h<=l; } string winner(int piles[], int size){ bool dp[size+1]; fill(dp,dp+size+1,false); for(int i=1;i<=size;++i){ for(int j=1;j<=i&&j<1000;++j){ // limit check for practical purposes if(is_palindrome(j)){ if(!dp[i-j]){ dp[i]=true;break; } } } } return dp[size]? "B":"E"; } int main(){ int T,pile_size; cin>>T; while(T--){ cin >> pile_size; cout << winner(&pile_size, pile_size)<<endl; } } ``` This code snippet demonstrates how to implement logic determining winners under given constraints using C++ language features effectively.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值