上午看啊哈算法的搜索,之前没懂的广搜 迷宫最短路径。
下午将昨天的八皇后问题解决了,然后洛谷刷了两题
晚上看了单词方阵(无果)
题目描述
一个如下的 6 \times 66×6 的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。
上面的布局可以用序列 2\ 4\ 6\ 1\ 3\ 52 4 6 1 3 5 来描述,第 ii 个数字表示在第 ii 行的相应位置有一个棋子,如下:
行号 1\ 2\ 3\ 4\ 5\ 61 2 3 4 5 6
列号 2\ 4\ 6\ 1\ 3\ 52 4 6 1 3 5
这只是棋子放置的一个解。请编一个程序找出所有棋子放置的解。
并把它们以上面的序列方法输出,解按字典顺序排列。
请输出前 33 个解。最后一行是解的总个数。输入格式
一行一个正整数 nn,表示棋盘是 n \times nn×n 大小的。
输出格式
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
输入输出样例
输入 #1复制
6输出 #1复制
2 4 6 1 3 5 3 6 2 5 1 4 4 1 5 2 6 3 4说明/提示
【数据范围】
对于 100\%100% 的数据,6 \le n \le 136≤n≤13。题目翻译来自NOCOW。
USACO Training Section 1.5
B站看视频讲解。从第一行开始,如果此地没被占领或攻击的到,就拿一个棋子占领此地,标记此地和能攻击到的地方,继续搜下一行,从第一列开始再判断,当最后一行某一列被找到时就输出。如果此行不行重新搜索记得回溯。
#include<stdio.h>
int n,x,s=0;
int p[50];//放置
int lie[50]={0};//这一列未占领
int h1[50]={0};//上斜对角线未被占领
int h2[50]={0};//下斜对角线未被占领
void dfs(int x)//行
{
for(int i=0;i<n;i++){//列
if(lie[i]==0&&h1[x-i+7]==0&&h2[x+i]==0){//都未被占领
p[x]=i;
lie[i]=1;
h1[x-i+7]=1;
h2[x+i]=1;//都标记已被占领
if(x<n-1) dfs(x+1);//找下一行
if(x==n-1){
s++;//总数
if(s<4){//输出前三个
for(int j=0;j<n;j++)
printf("%d ",p[j]+1);
printf("\n");
}
}
lie[i]=0;
h1[x-i+7]=0;
h2[x+i]=0;//回溯
}
}
}
int main()
{
scanf("%d",&n);
dfs(0);//从第一行开始
printf("%d\n",s);
}
题目描述
Due to recent rains, water has pooled in various places in Farmer John's field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water ('W') or dry land ('.'). Farmer John would like to figure out how many ponds have formed in his field. A pond is a connected set of squares with water in them, where a square is considered adjacent to all eight of its neighbors. Given a diagram of Farmer John's field, determine how many ponds he has.
由于近期的降雨,雨水汇集在农民约翰的田地不同的地方。我们用一个NxM(1<=N<=100;1<=M<=100)网格图表示。每个网格中有水('W') 或是旱地('.')。一个网格与其周围的八个网格相连,而一组相连的网格视为一个水坑。约翰想弄清楚他的田地已经形成了多少水坑。给出约翰田地的示意图,确定当中有多少水坑。
输入格式
Line 1: Two space-separated integers: N and M * Lines 2..N+1: M characters per line representing one row of Farmer John's field. Each character is either 'W' or '.'. The characters do not have spaces between them.
第1行:两个空格隔开的整数:N 和 M 第2行到第N+1行:每行M个字符,每个字符是'W'或'.',它们表示网格图中的一排。字符之间没有空格。
输出格式
Line 1: The number of ponds in Farmer John's field.
一行:水坑的数量
输入输出样例
输入 #1复制
10 12 W........WW. .WWW.....WWW ....WW...WW. .........WW. .........W.. ..W......W.. .W.W.....WW. W.W.W.....W. .W.W......W. ..W.......W.输出 #1复制
3说明/提示
OUTPUT DETAILS: There are three ponds: one in the upper left, one in the lower left, and one along the right side.
这题还是连通块的问题,只是多了四个方向, 周围的八个格子都要试一下。遍历每个格子,如果是W,就将与其连在一起的都赋 ' . ' ,这就是一块。
#include<stdio.h>
int N,M,sum=0;
char map[100][100];
int nx,ny;
int m[8][2]={1,0,-1,0,0,1,0,-1,1,1,-1,-1,1,-1,-1,1};
void dfs(int x,int y,int sum)
{
map[x][y]='.';
for(int i=0;i<8;i++){
nx=x+m[i][0];
ny=y+m[i][1];
if(nx<0||ny<0||nx>=N||ny>=M||map[nx][ny]=='.')
continue;
dfs(nx,ny,sum);
}
}
int main()
{
scanf("%d%d",&N,&M);
getchar();
for(int i=0;i<N;i++){
for(int j=0;j<M;j++)
scanf("%c",&map[i][j]);
getchar();
}
for(int i=0;i<N;i++){
for(int j=0;j<M;j++)
if(map[i][j]=='W')
dfs(i,j,sum++);
}
printf("%d\n",sum);
}
题目描述
Perket 是一种流行的美食。为了做好 Perket,厨师必须谨慎选择食材,以在保持传统风味的同时尽可能获得最全面的味道。你有 nn 种可支配的配料。对于每一种配料,我们知道它们各自的酸度 ss 和苦度 bb。当我们添加配料时,总的酸度为每一种配料的酸度总乘积;总的苦度为每一种配料的苦度的总和。
众所周知,美食应该做到口感适中,所以我们希望选取配料,以使得酸度和苦度的绝对差最小。
另外,我们必须添加至少一种配料,因为没有任何食物以水为配料的。
输入格式
第一行一个整数 nn,表示可供选用的食材种类数。
接下来 nn 行,每行 22 个整数 s_isi 和 b_ibi,表示第 ii 种食材的酸度和苦度。
输出格式
一行一个整数,表示可能的总酸度和总苦度的最小绝对差。
输入输出样例
输入 #1复制
1 3 10输出 #1复制
7输入 #2复制
2 3 8 5 8输出 #2复制
1输入 #3复制
4 1 7 2 6 3 8 4 9输出 #3复制
1说明/提示
数据规模与约定
对于 100\%100% 的数据,有 1 \leq n \leq 101≤n≤10,且将所有可用食材全部使用产生的总酸度和总苦度小于 1 \times 10^91×109,酸度和苦度不同时为 11 和 00。
说明
- 本题满分 7070 分。
- 题目译自 COCI2008-2009 CONTEST #2 PERKET,译者 @mnesia。
将每一种情况都取到,相互比较得最小值。
#include<stdio.h>
#include<math.h>
int n;
int s=1,b=0;
int s1[20],b1[20];
int sour[20]={0};//是否取过
int sum=9999999;
void dfs(int t)
{
for(int i=0;i<n;i++){
if(sour[i]==0){
s*=s1[i];
b+=b1[i];
if(sum>abs(s-b))
sum=abs(s-b);//两两相比
sour[i]=1;
dfs(i+1);
s/=s1[i];
b-=b1[i];
sour[i]=0;//回溯
}
}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d%d",&s1[i],&b1[i]);
dfs(0);//从第一个开始
printf("%d\n",sum);
}
明天还是搜索。