酸的命名(acid.cpp)
题目描述
化学于光羽而言简直是一个噩梦!请你帮他分辨这两种酸: polyatomic和non-metal。
ic
那么就是non-metal。格式
输入第一行,一个数q,表示询问个数。接下来q行,每行一个字符串描述化学用品。
输出一共q行,每行为non-metal acid或polyatomic acid或not an acid
范围
q <= 100
2 <= 字符串长度 <= 10000
没有什么算法,只要稍微加一些判断
程序如下:
#include
using namespace std;
int main()
{
freopen("acid.in","r",stdin);
freopen("acid.out","w",stdout);
int n;
string s="hydro";
char ch[10005];
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%s",&ch);
int len=strlen(ch);
if (ch[len-1]=='c'&&ch[len-2]=='i') //结尾为 ic
{
int f=1;
for (int j=0;j<5;j++)
if (ch[j]!=s[j]) {f=0;break;} //判断是不是 non-metal acid
if (f==1) cout<<"non-metal acid"; //如果是则输出 non-metal acid
if (f==0) cout<<"polyatomic acid"; //不是则输出 polyatomic acid
}
else cout<<"not an acid"; //不是酸
cout<
开锁大师(lock.cpp)
题目描述
开锁大师光羽上线了!!!
现在有n扇门,开始时,每扇门可能是开着也可能是关着的。大师的目标是把这些门都给打开。
每次大师可以选择一扇关着的门,把它打开。如果这扇门右边有门且它是关着的,大师会顺便把它一起打开。
请问,大师打开所有门,最少几次以及最多需要几次。
格式
输入第一行一个数n,第二行n个数,每个数是0或者1,1表示这扇门锁着,0表示开着。
输出两个数,表示最少和最多几次。
范围
N <= 10000
Sample Input
10
0 1 1 0 1 1 1 1 0 0
Sample Output
3 6
设当前门的状况为x
得知最大数即为有多少门是关着的
证明:
最坏的情况则是从最左边的关闭的们开始,由于是最左边关闭的门,所以它不存在 [右边的关着的门] ,所以max=关门数
实现:if (x==1) max++;
得知最小数即为有多少扇门可以连续开
证明:
最好的情况是有多道门可以连续开
实现:设当前连续的闭门数为 f ,
if (f%2==1) min++; min+=f/2;
#include
using namespace std;
int main()
{
freopen("lock.in","r",stdin);
freopen("lock.out","w",stdout);
int n,min=0,max=0,f=0,x;
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&x);
if (x==1) {max++;f++;} //门关着时:最大值+1,连续段+1
if (x==0)
{
if (f%2==1) min++; //公式
min+=f/2;
f=0;
}
}
if (f%2==1) min++; //如果结尾有一段关着的门就不会被扫描到,因此要多一次操作
min+=f/2;
printf("%d %d",min,max);
}
Problem 1 数学题(math.cpp/c/pas)
【题目描述】
给出一个n个未知数的方程,x[1],x[2],x[3]......x[n]
求x[1]+x[2]+x[3]....+x[n]==S的正整数解的个数,并且要保证,
对于任意i (1<=i< n) x[i]与x[i+1]相差不大于P;
【输入格式】
输入文件math.in
第一行三个整数n,S,P。
【输出格式】
输出文件math.out
一行一个整数表示方程解的个数。
【样例输入】
2 10 2
【样例输出】
3
【样例解释】
三种情况分别是:
5+5=10
4+6=10
6+4=10
【数据范围】
对于 30% 数据 2<=n<=10 ,p=0,S<=30;
对于 100% 数据 2<=n<=10,p<=3 , S<=30;
保证数据有梯度。
主体思想就是枚举每一个可能存在的 [初始值] ,然后判断相邻两个之间的差是否小于P,和是否等于S。
其实因为我们是从前到后一个一个搜索变量的值的,所以,每一个数的范围已经由上一个数的值确定了。所以这样搜索的状态就比较少了。
#include
using namespace std;
int s,n,p,t,a[100];
void dfs(int k,int x,int y) //k为当前搜到了k个数
//x为当前搜到的值的和
//y为上一个值(缩小搜索范围)
{
if (x==s&&k==n) t++; //满足条件
if (x>=s||k==n) return;
for (int i=max(y-p,1);i<=min(s,y+p);i++) //确定较为精准的范围
dfs(k+1,x+i,i); //搜索
}
int main()
{
freopen("math.in","r",stdin);
freopen("math.out","w",stdout);
scanf("%d%d%d",&n,&s,&p);
for (int j=1;j<=s;j++) dfs(1,j,j);
printf("%d",t);
}
农夫 John 正在研究他的农场的卫星照片.照片为一个R (1 <=
R <= 75) 行 C (1 <= C <= 75) 列的字符矩阵表示.如下图:
..................
..#####.......##..
..#####......##...
..................
#.......###.....#.
#.....#####.......
图上的一块相连通的 "#" 表示一群奶牛或一个房间, 两个子"#" 连通的意思是说左右或上下相连.而下面的两块则是分开的:
....
.#..
..#.
....
John现在根据卫星照片上的的这些"#"块的形状来判断哪些是牛群,哪些是房间.如果一个"#"块形状的边是水平或垂直的矩形,则是房间.其它的则认为都是牛群.在第一个图中,有三个房间 ( 2x1, 2x5, and 1x1)和2群牛.
请根据输入文件中的数据,统计出房间数和牛群数.
数据中牛群不会包围另一个牛群或房间.
输入格式: satel.in
* 第一行,两个整数: R 和 C.
* 和 2..R+1行: 第 i+1 行表示照片的第 i 行情况,由 C 字符组成.
输出格式:
* 第一行: 房间数.
* 第二行: 牛群数.
输入样例 (file satel.in):
5 8
#####..#
#####.##
......#.
.###...#
.###..##
输出样例 (file satel.out):
2
2
我的思路是先搜索出每一块牛或者房子,由于 [数据中牛群不会包围另一个牛群或房间] ,所以可以找出每一块区域的起点(mina,minb)和末尾(maxa,maxb),由于房子的格子数是等于(maxa-mina+1)*(maxb-minb+1) 的,所以可以根据这一条件来判断是房子还是牛
#include
using namespace std;
int mina,minb,maxa,maxb,ans,n,m;
char ch[80][80];
int dx[4]={1,-1,0,0}; //方位数组
int dy[4]={0,0,1,-1};
void dfs(int x,int y)
{
ch[x][y]='.';ans++; //统计.的个数
if (ymaxa) maxa=y; //行尾
if (x>maxb) maxb=x; //列尾
for (int i=0;i<4;i++)
{
int xi=x+dx[i];
int yi=y+dy[i];
if (ch[xi][yi]=='#'&&xi<=n&&yi<=m&&xi>0&&yi>0) dfs(xi,yi); //满足情况
}
}
int main()
{
freopen("satel.in","r",stdin);
freopen("satel.out","w",stdout);
scanf("%d%d",&n,&m);
int house=0,cow=0;
for (int i=1;i<=n;i++) //输入
{
ch[0][0]=getchar();
for (int j=1;j<=m;j++) ch[i][j]=getchar();
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
if (ch[i][j]=='#')
{
ans=0;mina=75;minb=75;maxa=0;maxb=0;
dfs(i,j);
int sum=(maxa-mina+1)*(maxb-minb+1); //如果当前图为房子应该的点数
if (sum!=ans) cow++; //与房子点数不符
else house++; //与房子点数相符
}
}
printf("%d\n%d",house,cow);
}