目录
1.1064问题 AE: 互不侵犯
时间限制: 1.000 Sec 内存限制: 128 MB
提交 状态
题目描述
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
输入
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
输出
方案数。
样例输入 Copy
3 2
样例输出 Copy
16
#include<bits/stdc++.h>
using namespace std;
const int N=12,M=1<<10,K=110;
vector<int>head[M];
vector<int>state;
long long f[N][K][M];
int n,m;
int cnt[M];
bool check(int state)
{
for(int i=0;i<n;i++){
if((state>>i&1)&&(state>>i+1&1)){
return false;
}
}
return true;
}
int count(int state)
{
int res=0;
for(int i=0;i<n;i++)res+=state>>i&1;
return res;
}
int main()
{
cin>>n>>m;
for(int i=0;i<1<<n;i++){
if(check(i)){
state.push_back(i);
cnt[i]=count(i);
}
}
for(int i=0;i<state.size();i++){
for(int j=0;j<state.size();j++){
int a=state[i],b=state[j];
if((a&b)==0&&check(a|b)){
head[i].push_back(j);
}
}
}
f[0][0][0]=1;
for(int i=1;i<=n+1;i++){
for(int j=0;j<=m;j++){
for(int k=0;k<state.size();k++){
for(auto b:head[k]){
int c=cnt[state[k]];
if(j>=c){
f[i][j][k]+=f[i-1][j-c][b];
}
}
}
}
}
cout<<f[n+1][m][0];
return 0;
}
每天写点题和题解 预防衰老
2.1097池塘计数问题 L: 数水塘
时间限制: 1.000 Sec 内存限制: 128 MB
提交 状态
题目描述
给定一个 N x M (1 <= N <= 100; 1 <= M <= 100) 的区域.每个区域用'W'表示有水,用.表示陆地。 如果一个区域有水且它相邻的区域也有水则同属一个水塘。一个区域最多有八个相邻的区域。根据,给定的地图现在要统计有多少个水塘。
输入
第一行:两个用空格隔开的整数N和M
第2..N+1行:每行M个字符,每个字符为 'W' 或 '.'。
输出
一行:一个整数表示水塘的个数
样例输入 Copy
10 12 W........WW. .WWW.....WWW ....WW...WW. .........WW. .........W.. ..W......W.. .W.W.....WW. W.W.W.....W. .W.W......W. ..W.......W.
样例输出 Copy
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
char g[N][N];
bool st[N][N];
int n,m;
typedef pair<int,int>PII;
void dfs(int x,int y)
{
queue<PII>q;
q.push({x,y});
while(!q.empty()){
int x=q.front().first,y=q.front().second;
q.pop();
for(int i=x-1;i<=x+1;i++){
for(int j=y-1;j<=y+1;j++){
if(i<0||i>=n||j<0||j>=m)continue;
if(g[i][j]=='.'||st[i][j])continue;
if(i==x&&j==y)continue;
q.push({i,j});
st[i][j]=true;
}
}
}
}
int main()
{
cin>>n>>m;
int ans=0;
for(int i=0;i<n;i++)cin>>g[i];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(!st[i][j]&&g[i][j]=='W'){
dfs(i,j);
ans++;
}
}
}
cout<<ans;
return 0;
}
3 1098 城堡问题
1 2 3 4 5 6 7
#############################
1 # | # | # | | #
#####---#####---#---#####---#
2 # # | # # # # #
#---#####---#####---#####---#
3 # | | # # # # #
#---#########---#####---#---#
4 # # | | | | # #
#############################
(图 1)
# = Wall
| = No wall
- = No wall
方向:上北下南左西右东。
图1是一个城堡的地形图。
请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大。
城堡被分割成 m∗nm∗n个方格区域,每个方格区域可以有0~4面墙。
注意:墙体厚度忽略不计。
输入格式
第一行包含两个整数 mm 和 nn,分别表示城堡南北方向的长度和东西方向的长度。
接下来 mm 行,每行包含 nn 个整数,每个整数都表示平面图对应位置的方块的墙的特征。
每个方块中墙的特征由数字 PP 来描述,我们用1表示西墙,2表示北墙,4表示东墙,8表示南墙,PP 为该方块包含墙的数字之和。
例如,如果一个方块的 PP 为3,则 3 = 1 + 2,该方块包含西墙和北墙。
城堡的内墙被计算两次,方块(1,1)的南墙同时也是方块(2,1)的北墙。
输入的数据保证城堡至少有两个房间。
输出格式
共两行,第一行输出房间总数,第二行输出最大房间的面积(方块数)。
数据范围
1≤m,n≤501≤m,n≤50,
0≤P≤150≤P≤15
输入样例:
4 7
11 6 11 6 3 10 6
7 9 6 13 5 15 5
1 10 12 7 13 7 5
13 11 10 8 10 12 13
输出样例:
5
9
#include<bits/stdc++.h>
using namespace std;
const int N=55;
int g[N][N];
bool st[N][N];
int n,m;
int dx[4]={0,-1,0,1},dy[4]={-1,0,1,0};
typedef pair<int,int>PII;
int bfs(int x,int y)
{
int area=0;
queue<PII>q;
q.push({x,y});
st[x][y]=true;
while(!q.empty())
{
auto t=q.front();
q.pop();
area++;
for(int i=0;i<4;i++){
int a=t.first+dx[i],b=t.second+dy[i];
if(a<0||a>=n||b<0||b>=m)continue;
if(st[a][b])continue;
if(g[t.first][t.second]>>i&1)continue;
q.push({a,b});
st[a][b]=true;
}
}
return area;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>g[i][j];
}
}
int ans=0,area=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(!st[i][j]){
area=max(area,bfs(i,j));
ans++;
}
}
}
cout<<ans<<endl<<area;
return 0;
}
4 1106 山峰和山谷
FGD小朋友特别喜欢爬山,在爬山的时候他就在研究山峰和山谷。
为了能够对旅程有一个安排,他想知道山峰和山谷的数量。
给定一个地图,为FGD想要旅行的区域,地图被分为 n×nn×n 的网格,每个格子 (i,j)(i,j) 的高度 w(i,j)w(i,j) 是给定的。
若两个格子有公共顶点,那么它们就是相邻的格子,如与 (i,j)(i,j) 相邻的格子有(i−1,j−1),(i−1,j),(i−1,j+1),(i,j−1),(i,j+1),(i+1,j−1),(i+1,j),(i+1,j+1)(i−1,j−1),(i−1,j),(i−1,j+1),(i,j−1),(i,j+1),(i+1,j−1),(i+1,j),(i+1,j+1)。
我们定义一个格子的集合 SS 为山峰(山谷)当且仅当:
- SS 的所有格子都有相同的高度。
- SS 的所有格子都连通。
- 对于 ss 属于 SS,与 ss 相邻的 s′s′ 不属于 SS,都有 ws>ws′ws>ws′(山峰),或者 ws<ws′ws<ws′(山谷)。
- 如果周围不存在相邻区域,则同时将其视为山峰和山谷。
你的任务是,对于给定的地图,求出山峰和山谷的数量,如果所有格子都有相同的高度,那么整个地图即是山峰,又是山谷。
输入格式
第一行包含一个正整数 nn,表示地图的大小。
接下来一个 n×nn×n 的矩阵,表示地图上每个格子的高度 ww。
输出格式
共一行,包含两个整数,表示山峰和山谷的数量。
数据范围
1≤n≤10001≤n≤1000,
0≤w≤1090≤w≤109
输入样例1:
5
8 8 8 7 7
7 7 8 8 7
7 7 7 7 7
7 8 8 7 8
7 8 8 8 8
输出样例1:
2 1
输入样例2:
5
5 7 8 3 1
5 5 7 6 6
6 6 6 2 8
5 7 2 5 8
7 1 0 1 7
输出样例2:
3 3
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int g[N][N];
bool st[N][N];
int n;
typedef pair<int,int>PII;
void bfs(int x,int y,bool& h,bool& l)
{
queue<PII>q;
q.push({x,y});
st[x][y]=true;
while(!q.empty()){
auto t=q.front();
q.pop();
int x=t.first,y=t.second;
for(int i=x-1;i<=x+1;i++){
for(int j=y-1;j<=y+1;j++){
if(i<0||i>=n||j<0||j>=n)continue;
if(g[i][j]!=g[x][y]){
if(g[i][j]>g[x][y])h=true;
else l=true;
}else if(!st[i][j]){
st[i][j]=true;
q.push({i,j});
}
}
}
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>g[i][j];
}
}
int peak=0,valley=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(!st[i][j]){
bool h=false,l=false;
bfs(i,j,h,l);
if(!h)valley++;
if(!l)peak++;
}
}
}
cout<<valley<<" "<<peak;
return 0;
}
5 1076 迷宫问题
给定一个 n×nn×n 的二维数组,如下所示:
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
数据保证至少存在一条从左上角走到右下角的路径。
输入格式
第一行包含整数 n。
接下来 nn 行,每行包含 nn 个整数 0 或 1,表示迷宫。
输出格式
输出从左上角到右下角的最短路线,如果答案不唯一,输出任意一条路径均可。
按顺序,每行输出一个路径中经过的单元格的坐标,左上角坐标为 (0,0)(0,0),右下角坐标为 (n−1,n−1)(n−1,n−1)。
数据范围
0≤n≤10000≤n≤1000
输入样例:
5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出样例:
0 0
1 0
2 0
2 1
2 2
2 3
2 4
3 4
4 4
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N=1010;
int n;
typedef pair<int,int>PII;
int g[N][N];
PII pre[N][N];
void dfs(int x,int y)
{
queue<PII>q;
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
q.push({x,y});
memset(pre,-1,sizeof pre);
pre[x][y]={0,0};
while(!q.empty())
{
auto t=q.front();
q.pop();
for(int i=0;i<4;i++){
int a=t.x+dx[i],b=t.y+dy[i];
if(a<0||a>=n||b<0||b>=n)continue;
if(g[a][b])continue;
if(pre[a][b].x!=-1)continue;
q.push({a,b});
pre[a][b]=t;
}
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>g[i][j];
}
}
dfs(n-1,n-1);
PII end(0,0);
while(1){
cout<<end.x<<" "<<end.y<<endl;
if(end.x==n-1&&end.y==n-1)break;
end=pre[end.x][end.y];
}
return 0;
}
6 1100 抓住那头牛
农夫知道一头牛的位置,想要抓住它。
农夫和牛都位于数轴上,农夫起始位于点 NN,牛位于点 KK。
农夫有两种移动方式:
- 从 XX 移动到 X−1X−1 或 X+1X+1,每次移动花费一分钟
- 从 XX 移动到 2∗X2∗X,每次移动花费一分钟
假设牛没有意识到农夫的行动,站在原地不动。
农夫最少要花多少时间才能抓住牛?
输入格式
共一行,包含两个整数N和K。
输出格式
输出一个整数,表示抓到牛所花费的最少时间。
数据范围
0≤N,K≤1050≤N,K≤105
输入样例:
5 17
输出样例:
4
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int f[N];
bool st[N];
int n,k;
int bfs()
{
queue<int>q;
q.push(n);
memset(f,-1,sizeof f);
f[n]=0;
while(!q.empty())
{
int t=q.front();
q.pop();
if(t==k)return f[k];
if(t+1<N&&f[t+1]==-1){
f[t+1]=f[t]+1;
q.push(t+1);
}
if(t-1>=0&&f[t-1]==-1){
f[t-1]=f[t]+1;
q.push(t-1);
}
if(t*2<N&&f[t*2]==-1){
f[t*2]=f[t]+1;
q.push(t*2);
}
}
}
int main()
{
cin>>n>>k;
cout<<bfs();
return 0;
}
好了 今天是1.13 浅浅刷这几道题吧