P1722 矩阵 II - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
一道会了就很简单的题;
先读题;
接下来提供一种不好的方法:深搜(会时间超限)当时乍一看就想到了搜;
先看代码:
#include<stdio.h>
int a[30000],r,h,n,zon;
void dfs(int i)
{
if(r>n||h>n)
return ;
if(i==2*n-1){
zon++;
zon%=100;
return ;
}
if(r>h){
a[i]=1;
r++;
dfs(i+1);
r-=1;
a[i]=0;
h++;
dfs(i+1);
h--;
}
else{
a[i]=1;
r++;
dfs(i+1);
r--;
}
return ;
}
int main()
{
scanf("%d",&n);//a[]=1就为红,0为黑
a[0]=1;
r++;
dfs(1);
printf("%d",zon);
return 0;
}
思路:先定义第一个数是红然后往下搜;如果红比黑多就走两次,反之就令他为红,最后记得判断当红或黑大于n是要返回重来;
因为有数据限定,所以可以考虑用dp(正态规划):
先看代码:
#include<stdio.h>
int dp[1000][1000];
int main()
{
int n;
scanf("%d",&n);
dp[1][1]=1;
for(int i=2;i<=n*2;i++){
for(int j=(i+1)/2;j<=i;j++){
dp[i][j]=(dp[i-1][j-1]+dp[i-1][j])%100;
}
}
printf("%d",dp[n*2][n]);
return 0;
}
这种方法比较难想,但想到了就特别容易。
注意:先定义dp[i][j]表示前面i个中有j个红;
因为前面的红色一定比黑色多所以不可能存在j>i/2;
这就是一个简单的正态规划代码。
[USACO1.5] 八皇后 Checker Challenge - 洛谷
一道搜索题:可以巩固我们的写代码能力
先看代码:
#include<stdio.h>
int n,a[200],book[3][200],sum;
void dfs(int i)
{
if(i>n){
sum++;
if(sum<=3){
for(int w=1;w<=n;w++){
printf("%d ",a[w]);
}
printf("\n");
}
}
for(int j=1;j<=n;j++){
if(book[0][j]==0&&book[1][i+j]==0&&book[2][i-j+n]==0){
a[i]=j;
book[0][j]=1;
book[1][i+j]=1;
book[2][i-j+n]=1;
dfs(i+1);
book[0][j]=0;
book[1][i+j]=0;
book[2][i-j+n]=0;
}
}
}
int main()
{
scanf("%d",&n);
dfs(1);
printf("%d",sum);
return 0;
}
思路:用book数组标记,借助dfs函数多次递归;
注意:行列好表示但对角线该如何表示呢
右上到左下:用i+j;
右下到左上:i-j,因为怕有负数所以一般加上一个数,这里加上n
P2105 K皇后 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这道题有异曲同工之妙;直接看·代码:
#include<stdio.h>
int book[200000],book1[200000],book2[200000],book3[200000];
int main()
{
int n,m,k,sum=0;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++){
int q,w;
scanf("%d %d",&q,&w);
book[q]=1;
book1[w]=1;
book2[q+w]=1;
book3[q-w+n+m]=1;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(book[i]==0&&book1[j]==0&&book2[i+j]==0&&book3[i-j+m+n]==0)
sum++;
}
}
printf("%d",sum);
return 0;
}