机器人大作战-oj选拔题(七道题-题目及源代码)

一、等凸函数

问题描述:

    定义一种数字称为等凹数字,即从高位到低位,每一位的数字先递减再递增,且该数是一个回文数,即从左读到右与从右读到左是一样的,仅形成一个等凹峰,如543212345,5544334455是合法的等凹数字,543212346,123321不是等凹数字。现在问你[L,R]中有多少等凹数字呢?L,R<=1e18(小于等于2位的无凹峰)

输入:

    第一行一个整数T,表示有T组数据,T <= 110.

    接下来的每行包含两个用空格分开的整数L R,保证L,R<=1e18.

    (如:输入“2 \n 1 100 \n 666 666666”)

输出:

    对于每组输入,在一行输出一个整数,代表[L,R]中等凹数字的个数。
    
    (“0 \n 356”)


源代码:

#include<iostream>
#include<cstring>
#include<sstream>
#include<cstdio>
using namespace std;
typedef long long ll;
int num(ll x) {
	int n=0;
	while(x) {
		n++;
		x/=10;
	}
	return n;
}
ll sum=0;
int a[20];
void dfs(int n,ll l,ll r,int p,int fa) {
	if(n==0) {
		int i=0;
		while(a[i]==-1)i++;
		int j=18;
		while(a[j]==-1)j--;
		ll su=0;
		int x=0;
		for(int k=j; k>=i; k--) {
			if(a[k]==a[j])x++;
			su=su*10+a[k];
		}
		if(x==j-i+1)return;
		if(su>=l&&su<=r) {
			sum++;
		}
		return;
	}
	for(int i=fa; i>=0; i--) {
		if(p) {
			a[9+n-1]=i;
			a[9-n+1]=i;
			dfs(n-1,l,r,p,i);
			a[9+n-1]=-1;
			a[9-n+1]=-1;
		} else {
			a[9+n]=i;
			a[9+1-n]=i;
			dfs(n-1,l,r,p,i);
			a[9+n]=-1;
			a[9+1-n]=-1;
		}
	}
}
void dfs_(int n,ll l,ll r) {
	if(n<=2)return;
	dfs((n+1)/2,l,r,n%2?1:0,9);
}
int main() {
	int T;
	cin>>T;
	while(T--) {
		sum=0;
		memset(a,-1,sizeof(a));
		ll l,r;
		cin>>l>>r;
		int s=num(l);
		int e=num(r);
		for(int i=s; i<=e; i++) {
			dfs_(i,l,r);
		}
		cout<<sum<<endl;
	}
	return 0;
}
二、两只老虎
问题描述;

    Tmk觉得很奇怪,因为在他面前突然出现了一群这样的老虎,有的没耳朵,有的没尾巴,不过也有正常的。

    现在Tmk告诉你这群老虎的耳朵个数,尾巴条数,以及老虎的腿的数目,问你有多少只是正常的。

    其中只有三种老虎:

    第一种(正常的):有2个耳朵、1条尾巴、4条腿

    第二种(没耳朵):有0个耳朵、1条尾巴、4条腿
    
    第三种(没尾巴):有2个耳朵、0条尾巴、4条腿

输入:
    第一行一个整数T表示有多少组样例。

    接下来每一行一个样例:

    包含三个整数a,b,c表示总共有a个耳朵,b条尾巴,c(<=4000)条腿,数据保证有解。
    
    (如:输入“1 \n    12 7 40”)

输出:
    对于每组样例输出一行,表示有多少只正常的老虎。
    
    (“3”)

源代码:

#include<stdio.h>
#include<functional>
#include<vector>
#include<queue>
#include<math.h>
#include<cstring>
#include<algorithm>
#include<iostream>
#define INF 9999999
using namespace std;
int main() {
	int n;
	scanf("%d",&n);
	while(n--) {
		int a,b,c;
		int a1,b1,c1;
		scanf("%d%d%d",&a,&b,&c);
		c1=c/4;
		b1=b;
		a1=a/2;
		printf("%d\n",a1+b1-c1);
	}
	return 0;
}
三、一道小学生算术题
问题描述:

    这是一道简单的小学生算术题,问题是这样的:给你四个整型数A,B,C,D,问其中的某一个数字能否通过其他三个数的加减乘除运算得到。每个数只能用一次。如果可以,则输出Yes,否则输出No。比如四个数为1,2,3,6.而1 + 2 + 3 = 6。所以输出Yes。如果四个数为2,2,3,9,则任意的三个数的运算,都不可能让等式成立。所以输出No。 提示:在计算机的整型数相除中,5 / 2 = 2,而我们问题中的算术,5 / 2 = 2.5。能帮你的只有这么多了...

输入:

    第一行输入一个整数t,表示有t组测试数据。 每组数据,输入四个整数,A,B,C,D。其中0 <= A,B,C,D <= 1000.

  (如:输入“2 \n 1 2 3 6  \n 2 2 3 9”)


输出:

    对于每组测试数据,按题意输出Yes或者No。

    (“Yes \n No”)

源代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define N 50
double a[N];
int vis[N];
double pai[N][N];
int q;
int judge;
#define eps 1e-4
void dfs_pai(int step,int pos) {
	if(step>4) {
		q++;
		return ;
	}
	for(int i=1; i<=4; i++) {
		if(vis[i])continue;
		pai[q][pos]=a[i];
		vis[i]=1;
		dfs_pai(step+1,pos+1);
		vis[i]=0;
	}
}

void dfs(int posi,int step,double answer) {
	if(judge)
		return ;
	if(step>3) {
		if(answer==pai[posi][4]) {
			judge=1;
		}
		return;
	}
	for(int i=1; i<=4; i++) {
		if(i==1)dfs(posi,step+1,answer+pai[posi][step]);
		if(i==2)dfs(posi,step+1,answer-pai[posi][step]);
		if(i==3)dfs(posi,step+1,answer*pai[posi][step]);
		if(i==4&&(pai[posi][step]!=0))dfs(posi,step+1,answer/pai[posi][step]);
	}
}
int main() {
#ifdef CDZSC
	freopen("i.txt","r",stdin);
#endif
	int t;
	scanf("%d",&t);
	while(t--) {
		judge=0;
		q=0;
		memset(pai,-1,sizeof(pai));
		memset(vis,0,sizeof(vis));
		for(int i=1; i<=4; i++)
			scanf("%lf",&a[i]);
		dfs_pai(1,1);
		for(int i=1; i<=4; i++) {
			int tt;
			for(int j=0; j<q; j++) {
				if(pai[j][i]>=0)tt=pai[j][i];
				else
					pai[j][i]=tt;
			}
		}
		memset(vis,0,sizeof(vis));
		for(int i=0; i<q; i++) {
			dfs(i,2,pai[i][1]);
			if(judge) {
				break;
			}
		}
		puts(judge?"Yes":"No");
	}
	return 0;
}
四、A-B 问题
问题描述:

    给出两个32位有符号整数(C、C++语言的int类型)范围内的数A,B

    求A-B的绝对值,即|A-B|。

输入:

    数据数据包含T+1行。

    第一行一个整数T(1<=T<=10000)。

    接下来T行,每行两个整数,分别代表A和B。

 (如:输入“3 \n 10 -10 \n 100 0 \n 12345 54321”)

扫描二维码关注公众号,回复: 1732191 查看本文章

输出:

    对于每组数据输出一行,每行一个整数,表示|A-B|。

    (“20 \n 100 \n 41976”)

源代码:

#include<stdio.h>

int value(int a,int b) {
	int temp;
	if(a>b)    temp=a-b;
	else   temp=b-a;

	return temp;
}

int main() {
	int a,b;
	int i,T;
	scanf("%d",&T);
	for(i=0; i<T; i++) {
		scanf("%d %d",&a,&b);
		printf("%d\n",value(a,b));
	}

	return 0;
}
五、谈恋爱
问题描述:
    在大学生涯中,谈恋爱是一个亘古不变的真理。女生恋爱时主要看你兜里有没有钱,家里有没有权。人脉够不够好,模样够不够帅。为此有人发明了一个指数a,表示一个人的综合魅力指数。
    在校园中,每个女孩子都会有一个指数区间,即是只有在这个区间的男生才能引起她的注意力。而对于不在该区间范围的不予考虑。有一天m个漂亮美眉迁到了ACM组.这时组里的n个光棍们兴奋了。已经通过各种渠道获取了这批美眉的指数区间,以及光棍们的魅力指数。剩下的事情便交给你了,问最多可以成多少对。

输入:
    多组测试数据。
    第一行 :m  n(美眉数  光棍数)m,n不大于500
    接下来m行:美眉们的指数区间 x y
    最后一行有n个数:对应的魅力值。
    (如:输入“3 2 \n 1 3 \n 2 4 \n 2 5 \n 1 3”)

输出:
    最多所能成的对数

    (“2”)

源代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N = 505;
struct MM {
	int x,y;
} mm[N];
int gg[N];
int n,m;
bool vis[N];
int lik[N];
int dfs(int t) {
	for(int i=0; i<m; i++) {
		if(!vis[i] && mm[i].x<=gg[t] && mm[i].y>=gg[t]) {
			vis[i]=1;
			if(lik[i]==-1 || dfs(lik[i])) {
				lik[i]=t;
				return 1;
			}
		}
	}
	return 0;
}
void max_num() {
	int ans=0;
	for(int i=0; i<n; i++) {
		memset(vis,0,sizeof(vis));
		if(dfs(i)) ans++;
	}
	printf("%d\n",ans);
}
int main() {
	while(~scanf("%d%d",&m,&n)) {
		memset(lik,-1,sizeof(lik));
		for(int i=0; i<m; i++)
			scanf("%d%d",&mm[i].x,&mm[i].y);
		for(int i=0; i<n; i++) scanf("%d",&gg[i]);
		max_num();
	}
	return 0;
}
六、甩伞
问题描述:

    胡老师对世界上所有可以经过可行计算后求解的问题都很好奇,下雨天到来时,他又对甩伞时水珠落地后的轨迹开始感兴趣了。

    假设伞的表面是半径位R m的圆,并在离地面高度h m处以角速度w rad/s转动。已知重力加速度g=9.8 m/(s^2),现在想知道水珠分布的最大半径是多少。

    我们假设水珠离开伞面时做平抛运动,并且忽略运动过程一切可能造成能量耗散的阻力。

输入:

    多组测试数据。

    每组测试数据只有一行,包含三个整数R,h以及w。 (1 <= R, h, w <= 100) 

   (如:输入“1 1 1”;)


输出;

    对于每组测试数据,输出一个小数代表水珠分布的最大半径,答案保留小数点后两位。

  (“1.10”;

源代码:

#include<stdio.h>
#include<math.h>
int main() {
	int r,h,w;
	while(scanf("%d%d%d",&r,&h,&w)!=EOF)
		printf("%.2f\n",sqrt(r*r+w*r*w*r*2*h/9.8));
	return 0;
}
七、这是物理学的奇迹

问题描述:

     goagain在做物理电学实验时需要一个2Ω的电阻,但是他发现他的实验台上只剩下了3Ω,4Ω,5Ω,6Ω的电阻若干,于是goagain把两个4Ω的电阻并联起来,发现效果也不错,于是他惊呼,这是物理学的奇迹!!

    实验结束之后goagain思考了一下,其实用1个3Ω的电阻和一个6Ω的电阻并联一下也是不错的,但是似乎没有其他的方法可以并联两个电阻得到等效的2Ω电阻了.

    goagain就想啊,如果我需要一个k Ω的电阻,但是我的手头上只有k+1 Ω,k+2 Ω,.....,一直到正无穷的整数Ω电阻,那么我有多少种办法把他们其中的两个并联起来,得到一个k Ω的电阻呢?

goagain仔细想了想,终于发现自己的智力不足以解决这样的问题,于是他不得不感叹:这真是物理学的奇迹!

输入要求:

    有多组测试数据,每组数据包含一个正整数k(k<2^16),处理到文件结束

  (输入:“3”)


输出要求

    对于每组测试数据,输出一个正整数,代表方法的总数

  (“2”)

源代码:

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

#include <iostream>
#include <cmath>
#include <algorithm>
#include <numeric>
#include <utility>

#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
using namespace std;

#define inf 0x3f3f3f3f
#define MAXN 800000

#define clr(x,k) memset((x),(k),sizeof(x))
#define clrn(x,k) memset((x),(k),(n+1)*sizeof(int))
#define cpy(x,k) memcpy((x),(k),sizeof(x))
#define Base 10000

typedef vector<int> vi;

#define foreach(it,c) for(vi::iterator it = (c).begin();it != (c).end();++it)

#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
bool is[MAXN];
int prm[MAXN];
int k;
int getprm(int n) {
	int i,j,k;
	for(i=0; i<n; i++) is[i]=true;
	is[0]=is[1]=false;
	k=0;
	for(i=2; i<n; i++) {
		if(is[i]) {
			prm[k++]=i;
			for(j=i+i; j<n; j+=i)
				is[j]=false;
		}
	}
	return k;
}

int fenjie(int n) {
	int i,zn,j,ans=1;
	for(i = 0,zn=prm[i]; prm[i]<=n; ++i,zn = prm[i]) {
		if(n%zn==0) {
			j=1;
			n/=zn;
			while(!(n%zn)) {
				n/=zn;
				j++;
			}
			ans*=(j+j+1);
		}

	}
	return ans+1;  //当n*n时
}
int main() {
	long long n;
	k=getprm(MAXN);

	while(scanf("%lld",&n)!=EOF) {
		if(n==1)printf("1\n");
		else printf("%d\n",fenjie(n)>>1);
	}
	return 0;
}
有问题欢迎指正!谢谢!

猜你喜欢

转载自blog.csdn.net/qq_38672855/article/details/79944751