【codevs】基础合集(二)

来源:互联网 发布:上海婚纱摄影推荐知乎 编辑:程序博客网 时间:2024/06/06 20:35

1083 Cantor表 1999年NOIP全国联赛普及组
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 白银 Silver

题目描述 Description
现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 1/5 … 2/1 2/2 2/3 2/4 … 3/1 3/2 3/3 … 4/1 4/2 … 5/1 … … 我们以Z字形给上表的每一项编号。第一项是1/1,然后是1/2,2/1,3/1,2/2,…

这里写图片描述

输入描述 Input Description
整数N(1≤N≤10000000)

输出描述 Output Description
表中的第N项

样例输入 Sample Input
7

样例输出 Sample Output
1/4

就按照第二个图 斜着看
第一行是1/1 第二行1/2 2/1 ……以此类推
每一行分母分子之和相同 而且是第几行就有几个
换句话说你给我一个n 我就能算出来第n个数是第几行
根据n的余数 还可以判断出是这一行的第几个
再注意一下奇数行和偶数行的顺序不同 就好啦

#include <iostream>#include <cstring>#include <cstdio>using namespace std;int n;int z;int main(){    scanf("%d",&n);    int i = 1;    while(n > i)//算行数    {        n -= i;//        i ++;    }    if(i & 1)//分子    {        z = i - n + 1;    }    else    {        z = n;    }    cout << z << "/";    cout << (i + 1) - z;//分母    return 0;}

orz 当年xczhw神犇的代码
23333我当年弱的这个题都不会
QAQ现在弱的不会讲
下个题下个题……

1160 蛇形矩阵
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 白银 Silver
题解
题目描述 Description
小明玩一个数字游戏,取个n行n列数字矩阵(其中n为不超过100的奇数),数字的填补方法为:在矩阵中心从1开始以逆时针方向绕行,逐圈扩大,直到n行n列填满数字,请输出该n行n列正方形矩阵以及其的对角线数字之和.

输入描述 Input Description
n(即n行n列)

输出描述 Output Description
n+1行,n行为组成的矩阵,最后一行为对角线数字之和

样例输入 Sample Input
3

样例输出 Sample Output
5 4 3
6 1 2
7 8 9
25

这题其实一句话可以A
“你可以倒着填啊”
从n * n,表内最后一格开始,倒着填回去,到最后的1
这样的话 已知最外层大小 就比较好做了
然而要注意边界

第二种 从里向外 先填最中心的1 然后转出来
这个难写一点点 为了判断什么时候可以拐弯
要善于利用没填的空位
比如哪里有空哪里拐什么的
╮(╯_╰)╭代码是从外向里

#include <iostream>#include <cstdio>#include <cstring>int a[105][105],n,i=0,j=0,c=1,sum=0;using namespace std;int main(){    memset(a,0,sizeof(a));    scanf("%d",&n);    c = n * n;    a[i=n][j=n] = c;//最后一个数    while(c > 1)    {//向里转        while(i-1> 0 && !a[i-1][j]) a[--i][j]=--c;        while(j-1> 0 && !a[i][j-1]) a[i][--j]=--c;        while(i+1<=n && !a[i+1][j]) a[++i][j]=--c;        while(j+1<=n && !a[i][j+1]) a[i][++j]=--c;    }    for(int i=1; i<=n; i++)    {        for(int j=1; j<=n; j++)            printf("%d ",a[j][i]);        printf("\n");    }    for(int x=1; x<=n; x++)//这是求和        sum+=a[x][x]+a[x][n+1-x];    cout<<sum-1;    return 0;}

都是以前的代码
其实printf 和 cout 一起用不是好习惯
嗯嗯
下一道

1294 全排列
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold

题目描述 Description
给出一个n, 请输出n的所有全排列

输入描述 Input Description
读入仅一个整数n (1<=n<=10)

输出描述 Output Description
一共n!行,每行n个用空格隔开的数,表示n的一个全排列。并且按全排列的字典序输出。

样例输入 Sample Input
3

样例输出 Sample Output
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

这个题啊特别经典
所谓理解就是 看明白它想让你干什么 && 知道自己怎么干

一般做法是枚举数字 看这一位上放这个数字 然后枚举下一个 一直搜完所有空位 适用于数字少
然而一般数字都 >= 空位 不然怎么做╮(╯_╰)╭
所以有了二般做法 枚举空位 填数 枚举下一个空位
对于当前这个空位我最多就n种可能 下一个空位就是n-1种
复杂度O(n!)

这里给出的代码是枚举空位

#include <iostream>#include <cstdio>#include <algorithm>int n,m;bool vis[11];//记录这个数字有没有用过int ans[11];//存储每次枚举的答案using namespace std;void putout()//输出{//枚举空位 答案按照字典序输出的话 就要倒着输出啦    for(int i = n; i >= 1; i--)        printf("%d ", ans[i]);    printf("\n");}void qpl(int x){    if(x > 0)//x表示空位,如果还有空位就向其中填数    {        for(int i = 1; i <= n; i++)            if(vis[i] == 0)//如果没被用过            {                ans[x] = i;//当前这个空位填上这个数                vis[i] = 1;//这个数被用过了                qpl(x - 1);//搜索剩下的空位                vis[i] = 0;//还原 假装什么都没有发生 这个数没被用过            }    }    else        putout();//没有空位了 输出}int main(){    scanf("%d",&n);    qpl(n);    return 0;}

当时绿神的代码
嗯嗯码力弱爆的人自己的代码丑的不想放博客

以上
总结一下
找规律找规律找规律
打表也得会打才能对

1 0
原创粉丝点击