ccf刷题记终极版02

当ccf撞上cccc,外加前有硬件课设,后有英语竞赛,就很难受,不过,不慌不忙,稳中求进,才是王道

来一套2015年12月的题,2minA题,20minB题,30minC题,留下3h强攻最后两题,然后由于好久没高强度训练了,注意了不免有点不集中,最终400分草草结束

201512-1 数位之和

思路:水题,分解整数,计算各位之和,秒杀级别,千万不能耽误任何时间

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 1e5+10;

int main()
{
    int n;
    scanf("%d",&n);
    int sum = 0;
    while(n)
    {
        sum += n%10;
        n /= 10;
    }
    printf("%d\n",sum);
    return 0;
}


201512-2 消除类游戏

思路:这题由于矩阵给的很小,于是最有效的方法就是做个最暴力的模拟暴搜

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 40;

int chess[maxn][maxn];
bool rechess[maxn][maxn];

int n,m;

void reduce(int x,int y)
{
    if(x+3<=n)
    {
        if(chess[x][y]==chess[x+1][y]&&chess[x][y]==chess[x+2][y])
        {
            int pos = x+3;
            while(pos<n&&chess[x][y]==chess[pos][y])
            {
                pos++;
            }
            for(int i=x;i<pos;i++)
            {
                rechess[i][y] = true;
            }
        }
    }
    if(y+3<=m)
    {
        if(chess[x][y]==chess[x][y+1]&&chess[x][y]==chess[x][y+2])
        {
            int pos = y+3;
            while(pos<m&&chess[x][y]==chess[x][pos])
            {
                pos++;
            }
            for(int i=y;i<pos;i++)
            {
                rechess[x][i] = true;
            }
        }
    }
    return ;
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(rechess,false,sizeof(rechess));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&chess[i][j]);
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                reduce(i,j);
            }
        }
        for(int i=0;i<n;i++)
        {
            if(rechess[i][0])
            {
                printf("%d",0);
            }
            else
            {
                printf("%d",chess[i][0]);
            }
            for(int j=1;j<m;j++)
            {
                if(rechess[i][j])
                {
                    printf(" %d",0);
                }
                else
                {
                    printf(" %d",chess[i][j]);
                }
            }
            printf("\n");
        }
    }
    return 0;
}


201512-3 画图

思路:这题完全可以分成两个子操作独立解决,对于画线就是根据原位置信息进行模拟,填充则是做一个dfs

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 110;

char paint[maxn][maxn];

int d[4][2] = { { 0, 1},
                { 0,-1},
                { 1, 0},
                {-1, 0} };

int m,n;

void drawline(int x1,int y1,int x2,int y2)
{
    if(x1==x2)
    {
        if(y1>y2)
        {
            int temp = y1;
            y1 = y2;
            y2 = temp;
        }
        for(int i=y1;i<=y2;i++)
        {
            if(paint[x1][i] == '+')
            {
                continue;
            }
            if(paint[x1][i] == '-')
            {
                paint[x1][i] = '+';
            }
            else
            {
                paint[x1][i] = '|';
            }
        }
    }
    else
    {
        if(x1>x2)
        {
            int temp = x1;
            x1 = x2;
            x2 = temp;
        }
        for(int i=x1;i<=x2;i++)
        {
            if(paint[i][y1] == '+')
            {
                continue;
            }
            if(paint[i][y1] == '|')
            {
                paint[i][y1] = '+';
            }
            else
            {
                paint[i][y1] = '-';
            }
        }
    }
    return ;
}

void dfsfillblock(int x,int y,char c)
{
    if(paint[x][y] == '+' || paint[x][y] == '-' || paint[x][y] == '|' || paint[x][y] == c)
    {
        return ;
    }
    paint[x][y] = c;
    for(int i=0;i<4;i++)
    {
        int dx = x + d[i][0];
        int dy = y + d[i][1];
        if(dx<0||dx>=m||dy<0||dy>=n)
        {
            continue;
        }
        dfsfillblock(dx,dy,c);
    }
}

int main()
{
    int q;
    while(cin >> m >> n)
    {
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                paint[i][j] = '.';
            }
        }
        cin >> q;
        while(q--)
        {
            int p;
            cin >> p;
            if(p==0)
            {
                int x1,x2,y1,y2;
                cin >> x1 >> y1 >> x2 >> y2;
                drawline(x1,y1,x2,y2);
            }
            else
            {
                int x,y;
                char c;
                cin >> x >> y >> c;
                //cout << "***" << c << "***" << endl;
                dfsfillblock(x,y,c);
            }
        }
        //cout << n << m << endl;
        for(int i=n-1;i>=0;i--)
        {
            for(int j=0;j<m;j++)
            {
                cout << paint[j][i];
            }
            cout << endl;
        }
    }
    return 0;
}


201512-4 送货(50分)

思路:看似一个简单的欧拉路径问题,一开始用链接矩阵暴力一发,由于没考虑到回路靠后原则导致只有20分进账,40分后,确实想不出什么别的问题了,猛然间发现时间已经超过1s了,果断改用优先队列形式邻接链表,并更改了一些小问题后,成功50分进账

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 1e4+10;

bool con[maxn][maxn];
int num[maxn];


struct cmp
{
    bool operator() (const int a,const int b)const
    {
        return a>b;
    }
};

priority_queue<int,vector<int>,cmp> q[maxn];

int main()
{
    int n,m;
    cin >> n >> m;
    memset(con,false,sizeof con);
    memset(num,0,sizeof num);
    for(int i=1;i<=n;i++)
    {
        while(!q[i].empty())
        {
            q[i].pop();
        }
    }
    for(int i=0;i<m;i++)
    {
        int a,b;
        cin >> a >> b;
        con[a][b] = true;
        con[b][a] = true;
        q[a].push(b);
        q[b].push(a);
        num[a] ++;
        num[b] ++;
    }
    int pos = 1;
    vector <int> re;
    //cout << m << "#" << endl;
    while(m)
    {
        //cout << m << "#" << endl;
        //int ne = 1;
        int temp = -1;
        //for(;ne<=n;ne++)

        //{
        while((!q[pos].empty())&&(!con[pos][q[pos].top()]))
        {
            q[pos].pop();
        }
        if(q[pos].empty())
        {
            break;
        }
        int ne = q[pos].top();
        q[pos].pop();
            //if(con[pos][ne])
            //{
        if(num[ne] == 1)
        {
            temp = ne;
            while((!q[pos].empty())&&(!con[pos][q[pos].top()]))
            {
                q[pos].pop();
            }
            if(!q[pos].empty())
            {
                ne = q[pos].top();
                q[pos].pop();
                q[pos].push(temp);
            }
        }
                //else
                //{
        re.push_back(ne);
        con[pos][ne] = false;
        con[ne][pos] = false;
        num[ne] --;
        num[pos] --;
        pos = ne;
                    //break;
                //}
            //}
        //}
        //cout << ne << "*" << m << "*" << endl;
        /*if(ne > n)
        {
            if(temp > 0)
            {
                re.push_back(temp);
                con[pos][temp] = false;
                con[temp][pos] = false;
                num[temp] --;
                num[pos] --;
                pos = temp;
            }
            else
            {
                break;
            }
        }*/
        m--;
    }
    if(m>0)
    {
        cout << "-1" << endl;
    }
    else
    {
        cout << 1;
        vector <int> :: iterator it = re.begin();
        for(;it!=re.end();it++)
        {
            cout << " " << (*it);
        }
        cout << endl;
    }
    return 0;
}

/*错误1:环路*/
/*错误2:细节,变量修改*/
/*错误3:超时,优先队列*/
/*错误4:起点序号*/
/*错误5:一致性,及时去除无效节点*/

201512-5 矩阵(50分)

思路:典型的矩阵快速幂问题,然而O(n^3)的矩阵运算对于稍微大一点的顶点数确实没什么好的方法,时间空间看似都没什么问题,但快速幂处的爆栈真心捉急,最后,水个小数据水50分吧

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 50+10;

typedef struct MATRIX
{
    int aa[maxn][maxn];
}Matrix;

int m;

Matrix A;

int b[maxn];

Matrix ama(Matrix &p,Matrix &q)//O(n^3)
{
    Matrix r;
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<m;j++)
        {
            r.aa[i][j] = 0;
            for(int z=0;z<m;z++)
            {
                r.aa[i][j] ^= (p.aa[i][z] & q.aa[z][j]);
            }
        }
    }
    return r;
}

Matrix ak(int k)//O(log(k))
{
    if(k==1)
    {
        return A ;
    }
    else if((k&1)==1)
    {
        Matrix temp = ak(k-1);
        return ama(temp,A);
    }
    else
    {
        Matrix temp = ak(k/2);
        return ama(temp,temp);
    }
}

void cal(Matrix p)
{
    int re;
    //cout << "#" << m << endl;
    for(int i=0;i<m;i++)
    {
        re = 0;
        //cout << re << "**" << endl;
        for(int j=0;j<m;j++)
        {
            re ^= (p.aa[i][j] & b[j]);
        }
        printf("%d",re);
    }
    printf("\n");
}

int main()
{
    //cout << "*" << endl;
    while(scanf("%d",&m)!=EOF)
    {
        //cout << "*"  << m << endl;
        //memset(ori,false,sizeof ori);
        //oria.clear();
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%1d",&A.aa[i][j]);
            }
        }
        for(int i=0;i<m;i++)
        {
            scanf("%1d",&b[i]);
        }
        int n;
        scanf("%d",&n);
        while(n--)
        {
            int k;
            scanf("%d",&k);
            if(k==0)
            {
                for(int i=0;i<m;i++)
                {
                    printf("%d",b[i]);
                }
                printf("\n");
            }
            else
            {
                cal(ak(k));
            }
        }
    }
    return 0;
}
/*爆栈*/

稍微定个小小的计划,最近几天一天一套题,估计可能还会剩两道题,但也是没办法的事了,谁让刚开学的时候自己有点浑浑噩噩沉迷吃鸡呢

至于ccf只能抽出零散时间来刷了,而未解决的ccf难题,都放到最后一天晚上吧和第二天上午吧

勿以往之不谏,预祝ccf和cccc都能取得好成绩吧

发布了97 篇原创文章 · 获赞 89 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Owen_Q/article/details/79556235