【校队+实验班】萌新训练赛【2】

ps:为讲解详细生动,个别注释参考了大佬的博客。

送分了QAQ 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述 

杭州人称傻乎乎的人为62,而嘟嘟家这里没有这样的习俗。

相比62,他那里的人更加讨厌数字38,当然啦,还有4这个

数字!所以啊,嘟嘟不点都不想见到包含38或者4的数字。

每次给出一个区间[n,m],你能找到所有令人讨厌的数字吗?

输入描述:

多组输入输出;
输入的都是整数对n、m(0如果遇到都是0的整数对,则输入结束。

输出描述:

对于每次的输入
输出全部令人讨厌的数的个数

示例1

输入

1 100
0 0

输出

20
#include<bits/stdc++.h>
const int N = 1e6 + 10;
using namespace std;
int a[N];
int judge(int n){
	while(n){
		if(n % 10 == 4||n % 100 == 38)
			return 1;
		n /= 10;	
	}	
	return 0;
} 
void oper(){
	a[0] = 0;
	for(int i = 1;i < N;i ++ ){
		if(judge(i)) a[i] = a[i-1] + 1;
		else a[i] = a[i-1];
	}
}
int main(){
	oper();//前缀和预处理
	int n,m;
	while(cin >> n >> m ){
        if(n == 0 && m == 0) return 0;
		cout << a[m] - a[n - 1];
        puts("");
	}
	return 0; 
} 

老子的全排列呢

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述 

老李见和尚赢了自己的酒,但是自己还舍不得,所以就耍起了赖皮,对和尚说,光武不行,再来点文的,你给我说出来1-8的全排序,我就让你喝,这次绝不耍你,你能帮帮和尚么?

输入描述:

输出描述:

1~8的全排列,按照全排列的顺序输出,每行结尾无空格。

示例1

输入

No_Input

输出

Full arrangement of 1~8

备注:

1~3的全排列  :
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
#include<bits/stdc++.h>
using namespace std;
int main(){
    int a[10];
    for(int i = 1;i <= 8;i ++ )
         a[i]=i;
    sort(a + 1,a + 1 + 8);//排序
    do{
        for(int i = 1;i <= 8;i ++ ){
            if(i == 1) cout << a[i];
            else cout << ' ' << a[i];
        }
        puts("");
    }while(next_permutation(a + 1,a + 1 + 8));//直接用函数不香吗
    return 0;
}

N皇后问题

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述 

给出一个n×n的国际象棋棋盘,你需要在棋盘中摆放nn个皇后,使得任意两个皇后之间不能互相攻击。具体来说,不能存在两个皇后位于同一行、同一列,或者同一对角线。请问共有多少种摆放方式满足条件。

输入描述:

一行,一个整数n(1\le n \le 12)n(1≤n≤12),表示棋盘的大小。

输出描述:

输出一行一个整数,表示总共有多少种摆放皇后的方案,使得它们两两不能互相攻击。

示例1

输入

4

输出

2
#include<bits/stdc++.h>      
using namespace std;  
int n;   
int a[15][15];  //棋盘
int judge_lie[15];  //检查同一列有没有皇后,没放就是0
int judge_zhu[30];  //检查主对角线
int judge_fu[30];  //检查副对角线
int now[15];  //用来暂时存下当前答案
int ans; 
void dfs(int i){//i行
	if (i > n){//搜索完每一行了
		ans++;  //答案总数加一
		return;  //搜索结束,返回上一个情况
	}
	for (int j = 1; j <= n; j++){//搜索这一行的每一个数据看符不符合要求
		if (!judge_lie[j] && !judge_zhu[i + j - 2] && !judge_fu[n - 1 + i - j]){//符合
			now[i] = j;   //记下第i行是第j个放下了棋子
			judge_lie[j] = 1;   //下面三行用来记录现在这个棋子的列,对角线都已经不能再放棋子了
			judge_zhu[i + j - 2] = 1;
			judge_fu[n - 1 + i - j]=1;
			dfs(i + 1);  //这一行放完了不能再放了,开始在这第i行第j个放下棋子的前提下搜索下一行
			judge_lie[j] = 0;  //搜索完第i行第j列放棋子的所有后续情况后,拿走,回溯,看看这第i行还有没有其它格子可以放棋子
			judge_zhu[i + j - 2] = 0;
			judge_fu[n - 1 + i - j] = 0;
			now[i] = 0;
		}
	}
}

int main(){
	cin >> n; 
	dfs(1);  //dfs搜索第一行
	cout << ans; 
	return 0;  
}

走出迷宫​​​​​​​

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述 

小明现在在玩一个游戏,游戏来到了教学关卡,迷宫是一个N*M的矩阵。

小明的起点在地图中用“S”来表示,终点用“E”来表示,障碍物用“#”来表示,空地用“.”来表示。

障碍物不能通过。小明如果现在在点(x,y)处,那么下一步只能走到相邻的四个格子中的某一个:(x+1,y),(x-1,y),(x,y+1),(x,y-1);

小明想要知道,现在他能否从起点走到终点。

输入描述:

本题包含多组数据。
每组数据先输入两个数字N,M
接下来N行,每行M个字符,表示地图的状态。
数据范围:
2<=N,M<=500
保证有一个起点S,同时保证有一个终点E.

输出描述:

每组数据输出一行,如果小明能够从起点走到终点,那么输出Yes,否则输出No

示例1

输入

3 3
S..
..E
...
3 3
S##
###
##E

输出

Yes
No
#include<bits/stdc++.h>
using namespace std;
const int N = 510;
char a[N][N];
int sign[N][N];
int n,m,flag;
int dx[4] = {1,0,-1,0} , dy[4] = {0,1,0,-1};//坐标的偏移量 
void dfs(int sx,int sy){
	if(a[sx][sy]=='E') flag = 1;//标记是否走到出口 
	for(int i = 0;i < 4;i ++ ){
		int x = sx + dx[i],y = sy + dy[i]; 
		if(x >= 0&& x < n && y >= 0&& y < m && a[x][y] != '#'&& !sign[x][y]){//前四个是判断当前位置是否出界,第五个是判断所在位置是否为通路,最后判断是否走过 
			sign[x][y] = 1;//标记当前位置走过了 
			dfs(x,y);//dfs下一个位置 
		}
	}
}
int main(){
	while(cin >> n >> m){ 
		int sx = 0,sy = 0;
		
		//恢复现场
		flag = 0;
		memset(a ,0, sizeof(a));
		memset(sign , 0 , sizeof(sign));
		
		//导入地图
		for(int i = 0;i < n;i ++ ){	
			for(int j = 0;j < m;j ++ ){
				cin>>a[i][j];
				if(a[i][j] == 'S'){//标记出口的位置 
					sx = i;sy = j;
				}
			}
		}
		dfs(sx,sy);//从起点开始dfs 
		if(flag) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
	return 0;
}

【NOIP2018】道路铺设

时间限制:C/C++ 1秒,其他语言2秒​​​​​​​

空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述 

春春是一名道路工程师,负责铺设一条长度为 n 的道路。
铺设道路的主要工作是填平下陷的地表。整段道路可以看作是 n 块首尾相连的区域,一开始,第 i 块区域下陷的深度为 di 。
春春每天可以选择一段连续区间 [L, R] ,填充这段区间中的每块区域,让其下陷深 度减少 1。在选择区间时,需要保证,区间内的每块区域在填充前下陷深度均不为 0 。
春春希望你能帮他设计一种方案,可以在最短的时间内将整段道路的下陷深度都变为0。

输入描述:

输入包含两行,第一行包含一个整数 n,表示道路的长度。 第二行包含 n 个整数,相邻两数间用一个空格隔开,第 i 个整数为 di。

输出描述:

输出文件仅包含一个整数,即最少需要多少天才能完成任务。

示例1

输入

6
4 3 2 5 3 5

输出

9

说明

一种可行的最佳方案是,依次选择:
[1,6]、[1,6]、[1,2]、[1,1]、[4,6]、[4,4]、[4,4]、[6,6]、[6,6]。

备注:

对于30%的数据,1 ≤ 𝑛 ≤ 10;

对于70%的数据,1 ≤ 𝑛 ≤ 1000; 

对于100%的数据,1 ≤ 𝑛 ≤ 100000,0 ≤ di ≤ 10000 。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n,a[N],f[N];//用f[i]表示前i个坑所铺设的最少天数
int main(){
	cin >> n;
	for(int i = 1;i <= n;i ++ ) cin >> a[i];
	f[1] = a[1];//初始化
	for(int i = 2;i <= n;i ++ ){
		if(a[i] <= a[i-1]) f[i] = f[i-1];//如果a[i] <= a[i-1],那么在填a[i-1]时就可以顺带把a[i]填上
		else f[i] = f[i-1] + (a[i] - a[i-1]);//否则在填a[i-1]时肯定要把a[i]一块填上,而a[i]剩余的就单独填
	}
	cout << f[n] << endl;
	return 0;
}

[NOIP2001]数的划分​​​​​​​

时间限制:C/C++ 1秒,其他语言2秒

空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述 

将整数n分成k份,且每份不能为空,任意两个方案不能相同(不考虑顺序)。
例如:n=7,k=3,下面三种分法被认为是相同的。

1,1,5; 

1,5,1; 

5,1,1;

问有多少种不同的分法。
输入:n,k ( 6 < n ≤ 200,2 ≤ k ≤ 6 )
输出:一个整数,即不同的分法。

输入描述:

两个整数 n,k ( 6 < n ≤ 200, 2 ≤ k ≤ 6 )

输出描述:

1个整数,即不同的分法。

示例1

输入

7 3

输出

4
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int main(){
  int n,k;
  cin >> n >> k;
  int dp[N][N];
  for(int i = 1;i <= n;i ++ ) dp[i][1] = 1;//输出1份即为自身,故为一种方案
  for(int i = 1;i <= n;i ++ )
    for(int j = 2;j <= k;j ++ )//注意从2开始
    //    假设是按递减排列
    //	n=7,k=3时可以有5 1 1, 4 2 1, 3 3 1, 3 2 2四种拆法,这些拆法可以分成两类,一是以1结尾,二是 >1的数结尾。
    //	以1结尾时,必然是把6分成2份然后最后加个1(5 1,4 2,3 3)
    //	以大于1的数结尾时说明所有数都大于1,
    //	此时只要先把3个位置都放上1,然后把剩下的4分成3份加上去,如3 2 2 -> 2 1 1即把4分成3份。
    //	dp[i][j] = dp[i-1][j-1](最后为1)+dp[i-j][j](最后大于1)
        if(i >= j) dp[i][j] = dp[i-1][j-1] + dp[i-j][j];//n >= k时才能有数分,故i >= j
  printf("%d\n",dp[n][k]);//从n中分出k份的方案数
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

那就随便一点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值