记录洛谷刷题qaq
[NOIP2001 提高组] 一元三次方程求解
题目描述
有形如: a x 3 + b x 2 + c x + d = 0 a x^3 + b x^2 + c x + d = 0 ax3+bx2+cx+d=0 这样的一个一元三次方程。给出该方程中各项的系数( a , b , c , d a,b,c,d a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在 − 100 -100 −100 至 100 100 100 之间),且根与根之差的绝对值 ≥ 1 \ge 1 ≥1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后 2 2 2 位。
提示:记方程 f ( x ) = 0 f(x) = 0 f(x)=0,若存在 2 2 2 个数 x 1 x_1 x1 和 x 2 x_2 x2,且 x 1 < x 2 x_1 < x_2 x1<x2, f ( x 1 ) × f ( x 2 ) < 0 f(x_1) \times f(x_2) < 0 f(x1)×f(x2)<0,则在 ( x 1 , x 2 ) (x_1, x_2) (x1,x2) 之间一定有一个根。
输入格式
一行, 4 4 4 个实数 a , b , c , d a, b, c, d a,b,c,d。
输出格式
一行, 3 3 3 个实根,从小到大输出,并精确到小数点后 2 2 2 位。
样例 #1
样例输入 #1
1 -5 -4 20
样例输出 #1
-2.00 2.00 5.00
提示
【题目来源】
NOIP 2001 提高组第一题
代码如下:
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
double a,b,c,d;
double fc(double x)
{
return a*x*x*x+b*x*x+c*x+d;
}
int main()
{
double l,r,m,x1,x2;
int s=0,i;
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
for (i=-100;i<100;i++)
{
l=i;
r=i+1;
x1=fc(l);
x2=fc(r);
if(!x1)
{
printf("%.2lf ",l);
s++;
}
if(x1*x2<0)
{
while(r-l>=0.001)
{
m=(l+r)/2; //middle
if(fc(m)*fc(r)<=0)
l=m;
else
r=m;
}
printf("%.2lf ",r);
s++;
}
if (s==3)
break;
}
return 0;
}
[NOIP2001 普及组] 数的计算
题目描述
我们要求找出具有下列性质数的个数(包含输入的正整数 n n n)。
先输入一个正整数 n n n( n ≤ 1000 n \le 1000 n≤1000),然后对此正整数按照如下方法进行处理:
-
不作任何处理;
-
在它的左边拼接一个正整数,但该正整数不能超过原数,或者是上一个被拼接的数的一半;
-
加上数后,继续按此规则进行处理,直到不能再加正整数为止。
输入格式
一行,一个正整数 n n n( n ≤ 1000 n \le 1000 n≤1000)。
输出格式
一个整数,表示具有该性质数的个数。
样例 #1
样例输入 #1
6
样例输出 #1
6
提示
【样例解释】
满足条件的数为: 6 6 6, 16 16 16, 26 26 26, 126 126 126, 36 36 36, 136 136 136。
【题目来源】
NOIP 2001 普及组第一题
代码如下:
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
int main(){
int n,cnt=1,i,f[1010];
f[0]=f[1]=1;
scanf("%d",&n);
for(i=2;i<=n;i++){
if(i%2==0){
f[i]=f[i-1]+f[i/2];
}else{
f[i]=f[i-1];
}
}
printf("%d\n",f[n]);
}
[NOIP2001 普及组] 最大公约数和最小公倍数问题
题目描述
输入两个正整数 x 0 , y 0 x_0, y_0 x0,y0,求出满足下列条件的 P , Q P, Q P,Q 的个数:
-
P , Q P,Q P,Q 是正整数。
-
要求 P , Q P, Q P,Q 以 x 0 x_0 x0 为最大公约数,以 y 0 y_0 y0 为最小公倍数。
试求:满足条件的所有可能的 P , Q P, Q P,Q 的个数。
输入格式
一行两个正整数 x 0 , y 0 x_0, y_0 x0,y0。
输出格式
一行一个数,表示求出满足条件的 P , Q P, Q P,Q 的个数。
样例 #1
样例输入 #1
3 60
样例输出 #1
4
提示
P , Q P,Q P,Q 有 4 4 4 种:
- 3 , 60 3, 60 3,60。
- 15 , 12 15, 12 15,12。
- 12 , 15 12, 15 12,15。
- 60 , 3 60, 3 60,3。
对于 100 % 100\% 100% 的数据, 2 ≤ x 0 , y 0 ≤ 10 5 2 \le x_0, y_0 \le {10}^5 2≤x0,y0≤105。
【题目来源】
NOIP 2001 普及组第二题
代码如下:
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
typedef long long ll;
int m,n,ans,flag;
ll gcd(ll x,ll y)
{
if(y==0) {return x;}
return gcd(y,x%y);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=sqrt(1ll*m*n);i++)
{
if((1ll*n*m)%i==0&&gcd(i,(1ll*n*m)/i)==n)
{
ans++;
if(1ll*i*i==1ll*n*m) flag=1;
}
}
printf("%d\n",2*ans-flag);
return 0;
}
[NOIP2001 普及组] 求先序排列
题目描述
给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,且二叉树的节点个数 $ \le 8$)。
输入格式
共两行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。
输出格式
共一行一个字符串,表示一棵二叉树的先序。
样例 #1
样例输入 #1
BADC
BDCA
样例输出 #1
ABCD
提示
【题目来源】
NOIP 2001 普及组第三题
代码如下:
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
char mid[20], aft[20];
void dfs(int ml, int mr, int al, int ar) {
if (ml > mr || al > ar) {
return;
}
printf("%c", aft[ar]);
for (int k = ml; k <= mr; k++) {
if (mid[k] == aft[ar]) {
dfs(ml, k-1, al, al+k-ml-1);
dfs(k+1, mr, al+k-ml, ar-1);
break;
}
}
}
int main(void) {
scanf("%s", mid);
scanf("%s", aft);
int len = strlen(mid) - 1;
dfs(0, len, 0, len);
return 0;
}
[NOIP2002 提高组] 均分纸牌
题目描述
有 N N N堆纸牌,编号分别为 1 , 2 , … , N 1,2,…,N 1,2,…,N。每堆上有若干张,但纸牌总数必为 N N N 的倍数。可以在任一堆上取若干张纸牌,然后移动。
移牌规则为:在编号为 1 1 1 堆上取的纸牌,只能移到编号为 2 2 2 的堆上;在编号为 N N N 的堆上取的纸牌,只能移到编号为 N − 1 N-1 N−1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。
现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。
例如 N = 4 N=4 N=4 时, 4 4 4 堆纸牌数分别为 9 , 8 , 17 , 6 9,8,17,6 9,8,17,6。
移动 3 3 3 次可达到目的:
- 从第三堆取 4 4 4 张牌放到第四堆,此时每堆纸牌数分别为 9 , 8 , 13 , 10 9,8,13,10 9,8,13,10。
- 从第三堆取 3 3 3 张牌放到第二堆,此时每堆纸牌数分别为 9 , 11 , 10 , 10 9,11,10,10 9,11,10,10。
- 从第二堆取 1 1 1 张牌放到第一堆,此时每堆纸牌数分别为 10 , 10 , 10 , 10 10,10,10,10 10,10,10,10。
输入格式
第一行共一个整数
N
N
N,表示纸牌堆数。
第二行共
N
N
N 个整数
A
1
,
A
2
,
⋯
,
A
N
A_1,A_2,\cdots,A_N
A1,A2,⋯,AN,表示每堆纸牌初始时的纸牌数。
输出格式
共一行,即所有堆均达到相等时的最少移动次数。
样例 #1
样例输入 #1
4
9 8 17 6
样例输出 #1
3
提示
对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 100 1 \le N \le 100 1≤N≤100, 1 ≤ A i ≤ 10000 1 \le A_i \le 10000 1≤Ai≤10000。
【题目来源】
NOIP 2002 提高组第一题
代码如下:
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
int n,a[101],mid,all,ans;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),all+=a[i];
all/=n;
for(int i=1;i<=n;i++)if(a[i]-all)
a[i+1]+=a[i]-all,ans++;
printf("%d",ans);
return 0;
}