暑期集训已经开始两天了,有种被拖着跑的感觉,我感觉自己的基础太差了,有些简单的动态规划,能听懂,思路也不难,就是自己打的时候,全是bug,连深搜,广搜的算法都需要看一两天才能明白具体的内容,究其根本还是打的代码太少,所以我觉得自己还是应该从基本的编程基础开始,在刷题中,巩固境界,一点点的进步,毕竟每个人的情况不一样嘛。
蛇形填数
给定一个 n , 在 n * n 的方阵中填入 1 ,2, 3,……,n * n, 要求填成蛇形。
例如在 n = 5 时 , 如下所示:
13 14 15 16 1
12 23 24 17 2
11 22 25 18 3
10 21 20 19 4
9 8 7 6 5
思路:
设置一个二维数组, 以 x 代表行, y 代表列
填数的顺序是 下, 左, 上, 右
直到一个方向无法再填数时,再进行下一个方向的填数
#include<bits/stdc++.h>
#include<iostream>
#define max 20 //max的值不能太大,否则程序无法运行
using namespace std;
int main()
{
int n,x,y;
cin >> n;
x=0;
y=n-1;
int a[max][max];
memset(a,0,sizeof(a));//及时的初始化
int top=0;
top=a[x][y] = 1;//也可以赋值到这里面。
while(top<n*n)//不超过最大值,同时注意不要++放前面和后面的用法
{
while(x+1<n && !a[x+1][y]) a[++x][y] = ++top;//从最外面先向下
while(y-1>=0 && !a[x][y-1]) a[x][--y] = ++top;//再往 左
while(x-1>=0 && !a[x-1][y]) a[--x][y] = ++top;//再往上
while(y+1<n && !a[x][y+1]) a[x][++y] = ++top;// 再往右
//学会如何去用坐标控制方向,在bfs,dfs算法中也用的上,!a[x+1][y]表示,超过格子范围的数不存在
}
for(x=0;x<n;x++)
{
for(y=0;y<n;y++)
{
printf("%3d",a[x][y]);//这样使打印的矩阵排列整齐
}
cout<<endl;
}
return 0;
}
开灯问题
n盏灯,编号为1-n,第一个人把所有灯打开,第二个人按下所有编号两倍的开关(这些灯被关掉),第三个人按下所有编号三倍的开关,以此类推,一共有k个人,问最后有哪些灯开着?
输入:n和k,输出开着的灯的编号,k<=n<=1000
样例输入:
7 3
样例输出:
1 5 6 7
算法思路:
其实我们可以采用数组存储多少盏灯的状态,然后模拟接下来的人开关灯的操作,怎么模拟?比如我们设置两个循环,第一个循环是操作的人,第二个循环是对所有的灯循环,通过第二个循环中我们拿每一盏灯的序号来和第几个人操作的来进行取余运算,如果为0,则模拟开关灯操作,就是将数组的值取相反值即可。
#include
#include
#include
using namespace std;
int num[1001]; //定义一个数组,保存灯的状态0为关闭,1为打开
int main()
{
memset(num,0,sizeof(num)); //给数组初始化全部为0
int n,k;
cin>>n>>k;//代表灯的个数和人的人数
int flag = 1; //这个flag标识变量是用来判断输出是否为第一个 ,节省多出来的空格
for(int i = 1;i<=k;i++){ // 这两个循环是模拟开关灯操作
for(int j = 1;j<=n;j++){ //第一个循环是代表开关灯的倍数,第二个循环是判断开关灯状态以及修改操作
if(j%i == 0) num[j] = !num[j];//相当于赋值为一,注意这个循环的过程
}
}
for(int i = 1;i<=100;i++){
if(num[i]){
if(flag) flag = 0; //这个是判断输出是否为第一个,是一个输出的技巧避免多出一个空格
else cout<<" ";
cout<<i;
}
}
cout<<endl;
return 0;
}
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/114910.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...