周报1

补题1:密码脱落

题意:给出一个字符串,问最少添加几个字符让该字符串成为回文串.

做法:(回文的特性)倒转字符串,找出最长公共子序列,即为最长回文子序列。故n减去最长回文子序列即答案. 

int dp[1003][1003]={0};
void solve(){                         //I   o(n^2) 
    string str0,str1;
    cin>>str0;
    str1=str0;
    reverse(str0.begin(),str0.end());
    int n=str0.size();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(str0[i-1]==str1[j-1]) dp[i][j]=dp[i-1][j-1]+1;
            else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
        }
    }
    cout<<n-dp[n][n];
}

补题2:弹球

题意:在给定初始格子和弹跳距离的条件下,通过删除格子或添加平台,使弹球越过终点。输出最小操作代价。

做法:!!预处理!!,o(n)预处理每个格子 i 是会被哪个路径经过,且如果是0,cnt[i%k]++; 再o(n)遍历一遍o(1)求出每个代价(Min_ans),若起点 i 就是0, cnt[i%k]--;

补题3:工程师Artem

题意:给定一个n*m的数字矩阵,要求每个数字可以增加0或1,使得新矩阵中相邻(上下左右)的数字都不相同。答案输出任意一个符合的矩阵即可。

做法:考虑 !!奇偶性!! 即可!。赛时没有反应过来,一直在想其他方法。

补题4:二进制表(hard)

题意:给定一个仅由0,1组成的n*m矩阵,可以在任一个2*2中选择其中3个数字使其翻转的操作。要求最多进行n*m次操作,使矩阵全为0,输出次数以及每次选择哪3个点。(大模拟)

做法:easy版本,最多可以进行3*n*m次操作,而hard版本最多可以进行n*m次操作。即每单次操作,最少有一个1变为0;通过分析可以发现,在一个2*2矩阵,如果需要变为全0有5种情况:         0个1--0次,1个1--3次,2个1--2次,3个1--1次,4个1--4次。对于eazy版本,直接遍历每一个2*2直接操作变为全0即可,但是实际上可能有浪费次数的。在只有1个1的情况下,要变为全0,需要3次,浪费了两次。换一种思路----因为n*m个点,最多可以进行n*m次,那么可以每次只转换当前点,不考虑其余两个点,因为后面遍历到会进行相应操作。遍历每一个点,只转换当前点。最后2*2则正常操作,最差需要4次,4个点最差要4次,也符合限制。前面全是对于前n-1行以前的是可行的,但是最后两行则不行,因为最后一行无法单独遍历,最后一行会影响上一行操作过的点。所以最后两行需要合并起来考虑,从左往右,一列一列遍历,如果该列有两个1,则选择这两个1,以及后一列任一个位置(同样后面遍历会进行相应操作,只需考虑当前列即可);如果该列只有一个1,那么选择这个1和后一列;如此操作,直至最后2*2,总次数一定不超过n*m。

 

总结:这周打的比赛,赛时没有做出来的题目,基本上能补的题的都补了,有一两道题是实在弄不明白,就先放着了。做的题感觉都还行,还能保持大脑运转和手感。慢慢适应训练节奏,再接再厉。还得尽量完成题单和补题的同时,挤点时间学点还没掌握的基本算法。

 

posted @ 2024-01-23 19:15  osir  阅读(1)  评论(0编辑  收藏  举报