CCF201312 小结

出现次数最多的数

除了用数组下标储存值(a[x]=count)外,还可以使用map容器。map的函数包括容器都有的begin(),end(),clear(),size()等,本题使用迭代器遍历map,找出最大值:

    int maxn=0,ans;
    for(map::iterator it=m.begin();it!=m.end();it++){
        if(it->second>maxn){
            maxn=it->second;  //it->first,it->second分别表示关联中左侧的值和右侧的值
            ans=it->first;
        }
    }
ISBN号码

使用string读取输入再根据题意处理,做这道题的时候新建了一个数组用于储存正确的数字,但这个数组是多余的,只需要计算并修改输入的字符串就可以了。

最大的矩形

暴力,没有想到更佳的解决方法。遍历方式可以是长方形的宽,但更优的方式是遍历长方形的高。

有趣的数

1.读题应该仔细,做题时因为理解错题意浪费很多时间。
2.用动态规划解决问题时可以想国王开金矿的问题,画出状态关系的树,这样就很好理解了。本题通过推导条件可以得出开头数字一定是2等额外条件,在这基础上想到长度为n的数字可以理解为一个长度为n-1的数加一个数,从而寻找到其他状态,接着将得到的状态继续分解,找到边界状态,也就是一个只包含数字2的数字。(国王不能解决问题,就把金矿分成n-1和1,再将n-1个金矿的问题交给大臣,以此类推。)
这样自顶向下分析问题,再写程序由下向上得到答案。
虽然现在理解了做法,但是当时还是没做出。下次如果卡住了就想想国王和金矿,看能不能用动态规划求解。
代码:

#include
#include
using namespace std;
const long long mod=10^9+7;
long long dp[1005][6];
int main(){
    int n;cin>>n;
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++){
        dp[i][0]=1;
        dp[i][1]=(dp[i-1][1]+dp[i-1][0])%mod;
        dp[i][2]=(dp[i-1][0]+dp[i-1][2]*2)%mod;
        dp[i][3]=(dp[i-1][2]+dp[i-1][3]*2)%mod;
        dp[i][4]=(dp[i-1][4]*2+dp[i-1][1]+dp[i-1][2])%mod;
        dp[i][5]=(dp[i-1][5]*2+dp[i-1][3]+dp[i-1][4])%mod;
    } 
    cout<
I'm stuck!

思路容易想出,但实现较难,主要原因是:
1.需要重复处理边界和方向判断,代码量较多
2.需要进行两次dfs,感觉有简化的实现方式,但不知道如何下手
3.做到这里耐心和专注度已经很少了,没法认真下来写好代码
后来参考标准答案写完代码,里面有很多可学习的地方:

#include
#include
using namespace std;
const int N=55;
struct _direct{   //用结构体处理方向 
    int dr,dc;
}direct[4]={{-1,0},{1,0},{0,-1},{0,1}};

char grid[N][N];
int vis1[N][N],vis2[N][N];

int R,C;

inline bool islegal(int r,int c){  //inline用于节约栈内存 
    return 0<=r&&r>R>>C;
    for(int i=0;i>grid[i];    //直接输入数组 
        
    for(int i=0;i
总结

第一次做ccf,难度超过自己的能力,如果现在就去考的话应该分数不高。这五道题有很多可学习的点:
1.容器map的使用(m->first,m->second,iterator)
2.识别动态规划的方法:国王的金矿
3.创建结构体_direct处理方向的问题,创建islegal处理边界的问题,灵活使用dfs中的vis表(memcpy)
4.*耐心的实现代码
还有很多地方可以提高~

你可能感兴趣的:(CCF201312 小结)