1.
题目描述
一个如下的 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
这个题的话就是一个经典的bfs的例题数据范围也不大
我的大致思路就是先将皇后在的点标记然后继续搜索知道你个点全找到了,然后再输出,主要的问题是解决对角线标记的问题,对角线的话其实有个规律就是从左下往右上的对角线行和列相加相等,从右下网左上的对角线行和列相减的值相等,那么这题就很好解决了
代码如下:
#include<stdio.h>
int a[40],b[40],c[40],d[40],e[15][15];
int o,n;
void dfs(int k)
{
if(k>n){
o++;
if(o<=3){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(e[i][j]){
printf("%d ",j);
}
}
}
printf("\n");
}
return ;
}
for(int i=1;i<=n;i++){
if(!b[i]&&!c[i+k]&&!d[k-i-1+n]){
e[k][i]=1;
a[i]=1;
b[i]=1;
c[i+k]=1;
d[k-i-1+n]=1;
dfs(k+1);
e[k][i]=0;
a[i]=0;
b[i]=0;
c[i+k]=0;
d[k-i-1+n]=0;
}
}
}
int main()
{
scanf("%d",&n);
dfs(1);
printf("%d\n",o);
return 0;
}
2.
网上流传一句话:"常在网上飘啊,哪能不挨刀啊~"。其实要想能安安心心地上网其实也不难,学点安全知识就可以。
首先,我们就要设置一个安全的密码。那什么样的密码才叫安全的呢?一般来说一个比较安全的密码至少应该满足下面两个条件:
(1).密码长度大于等于8,且不要超过16。
(2).密码中的字符应该来自下面“字符类别”中四组中的至少三组。
这四个字符类别分别为:
1.大写字母:A,B,C...Z;
2.小写字母:a,b,c...z;
3.数字:0,1,2...9;
4.特殊符号:~,!,@,#,$,%,^,&;
给你一个密码,你的任务就是判断它是不是一个安全的密码。
输入
输入数据第一行包含一个数M,接下有M行,每行一个密码(长度最大可能为50),密码仅包括上面的四类字符。
输出
对于每个测试实例,判断这个密码是不是一个安全的密码,是的话输出YES,否则输出NO。
样例输入 复制
3
a1b2c3d4
Linle@ACM
^~^@^@!%
代码如下:
#include<stdlib.h>
#include<string.h>
int main()
{
int len, n;
int i, j;
char str[100];
scanf( "%d\n", &n );
while( n-- )
{
int t[4] = {0};
gets( str );
len = strlen( str );
if( len < 8 || len > 16 )
printf( "NO\n" );
else
{
for( i = 0; i < len; i++ )
if(( str[i] >= 'A' ) && ( str[i] <= 'Z' ))
t[0]++;
else
if(( str[i] >= 'a' ) && ( str[i] <= 'z' ))
t[1]++;
else
if(( str[i] >= '0' ) && ( str[i] <= '9' ))
t[2]++;
else
t[3]++;
int x = 0;
for( i = 0; i < 4; i++ )
if( t[i] > 0 )
x++;
if( x >= 3 )
printf("YES\n");
else
printf("NO\n");
}
}
system( "pause" );
return 0;
}
就是一个很简单的字符串判断的问题
3.
小兔子有n个果园,果园里有许多果树,有苹果树,芒果树,香蕉树,李子树,无花果树。
终于到了丰收的季节,小兔子从每个果园采了许多的水果,现在小兔子想给每个果园的产量排序。
因为小兔子爱吃芒果,所以按芒果的数量从大到小排序,如果芒果的数量相同,那就按照其他水果的总数量从小到大排序。
不会存在芒果数量相同且其他水果的总数量相同的情况。
输入
第一行输入一个n,代表n个果园(1<=n<=10)
接下来n行,每行五个数,分别代表小兔子从果园里采摘的苹果数量,芒果数量,香蕉数量,李子数量,无花果数量
每个水果的数量不超过10,且没有负数。
输出
输出n个果园产量排序后的结果
样例输入 复制
5
1 2 3 4 5
1 3 3 4 5
1 4 2 2 2
1 1 1 1 1
1 4 1 1 1
样例输出 复制
代码如下:
#include<stdio.h>
struct node{
int a,b,c,d,e;
};
struct node f[1000];
struct node g[1000];
int main()
{
int n,t;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d %d %d %d %d",&f[i].a,&f[i].b,&f[i].c,&f[i].d,&f[i].e);
}
for(int i=0;i<n-1;i++)
{
for(int j=0;j<n-i-1;j++)
{
if(f[j].b>f[j+1].b)
{
g[j]=f[j];
f[j]=f[j+1];
f[j+1]=g[j];
}
if(f[j].b==f[j+1].b)
{
if(f[j].a+f[j].c+f[j].d+f[j].e<f[j+1].a+f[j+1].c+f[j+1].d+f[j+1].e)
{
g[j]=f[j];
f[j]=f[j+1];
f[j+1]=g[j];
}
}
}
}
for(int i=n-1;i>=0;i--){
printf("%d %d %d %d %d",f[i].a,f[i].b,f[i].c,f[i].d,f[i].e);
printf("\n");
}
}
先用一个结构体来储存数据然后用冒泡排序处理数据
最后直接输出数据
4.
给定一个长度为n的序列a,选出其中连续且非空的一段使得这一段的和最大。
输入
第一行输入一个整数n (n < 1e5)
第二行输入n个整数a[i] (-1e4 < a[i] < 1e4)
输出
输出这个序列中最大的子段和。
样例输入 复制
7
2 -4 3 -1 2 -4 3
样例输出 复制
样例输出
4
代码如下:
#include<stdio.h>
int a[200001];
int main()
{
int n ;
scanf("%d",&n);
for(int i = 0;i < n;i++)
{
scanf("%d" ,&a[i]);
}
int x = 0,max = a[0];
for(int i = 0;i < n;i++)
{
x += a[i];
if(x >= max)
max = x;
if(x <= 0)
x = 0;
}
printf("%d",max);
return 0;
}