P1022 [NOIP2000 普及组] 计算器的改良
题目背景
NCL 是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手 ZL 先生。
题目描述
为了很好的完成这个任务,ZL 先生首先研究了一些一元一次方程的实例:
- 4+3x=8。
- 6a−5+1=2−2a。
- −5+12y=0。
ZL 先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及 +
、-
、=
这三个数学符号(当然,符号“-
”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。
你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。
输入格式
一个一元一次方程。
输出格式
解方程的结果(精确至小数点后三位)。
输入输出样例
输入 #1复制
6a-5+1=2-2a
输出 #1复制
a=0.750
这里我分成了两部分一个是合并同类项等号左边的值,一个是合并同类项等号右边的值,然后将他们移项得出结果。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
char a[1010];
float b[1010];
float c[1010];
int main()
{
int i,j,flag=1,len,iszimu=0;
float coun1=0,coun2=0;
cin>>a;
char ch;
if(a[0]=='-')
flag=-1;
len=strlen(a);
float sum=0;
for(i=0;a[i]!='=';i=j+1)//算出等号左边的值
{ iszimu=0;
sum=0;
for(j=i;;j++)
{
if(a[j]>='a'&&a[j]<='z')
{iszimu=1;ch=a[j];}
if(a[j]=='+'||a[j]=='-'||a[j]=='=')
break;
}
if(iszimu)
if(a[i]==a[j-1])
sum=1;
for(int k=i;k<j;k++)
{
if(a[k]>='0'&&a[k]<='9')
sum=sum*10+a[k]-'0';
}
sum=sum*flag;
if(iszimu)
coun1+=sum;
else
coun2+=sum;
if(a[j]=='-')
flag=-1;
else
if(a[j]=='+')
flag=1;
if(a[j]=='=')
break;
}
// cout << coun1<<' '<<coun2<< endl;
float kk1=0,kk2=0;
i=j+1;
flag=1;
if(a[i]=='-')
flag=-1;
for(;i<len;i=j+1)//算右边的值
{ iszimu=0;
sum=0;
for(j=i;;j++)
{
if(a[j]>='a'&&a[j]<='z')
{iszimu=1;
ch=a[j];}
if(a[j]=='+'||a[j]=='-'||j>=len)
break;
}
if(iszimu)
if(a[i]==a[j-1])
sum=1;
for(int k=i;k<j;k++)
{
if(a[k]>='0'&&a[k]<='9')
sum=sum*10+a[k]-'0';
}
sum=sum*flag;
if(iszimu)
kk1+=sum;
else
kk2+=sum;
if(a[j]=='+')
flag=1;
else
if(a[j]=='-')
flag=-1;
}
// cout << kk1<<' '<<kk2<< endl;
printf("%c=%.3f",ch,(coun2-kk2)/(kk1-coun1));
return 0;
}
P1678 烦恼的高考志愿
题目背景
计算机竞赛小组的神牛 V 神终于结束了高考,然而作为班长的他还不能闲下来,班主任老 t 给了他一个艰巨的任务:帮同学找出最合理的大学填报方案。可是 v 神太忙了,身后还有一群小姑娘等着和他约会,于是他想到了同为计算机竞赛小组的你,请你帮他完成这个艰巨的任务。
题目描述
现有 m 所学校,每所学校预计分数线是 ai。有 n 位学生,估分分别为 bi。
根据 n 位学生的估分情况,分别给每位学生推荐一所学校,要求学校的预计分数线和学生的估分相差最小(可高可低,毕竟是估分嘛),这个最小值为不满意度。求所有学生不满意度和的最小值。
输入格式
第一行读入两个整数 m,n。m 表示学校数,n 表示学生数。
第二行共有 m 个数,表示 m 个学校的预计录取分数。第三行有 n 个数,表示 n 个学生的估分成绩。
输出格式
输出一行,为最小的不满度之和。
输入输出样例
输入 #1复制
4 3 513 598 567 689 500 600 550
输出 #1复制
32
说明/提示
数据范围:
对于 30%30% 的数据,1≤n,m≤1000,估分和录取线 ≤10000≤10000;
对于 100%100% 的数据,1≤n,m≤100000,估分和录取线 ≤1000000≤1000000 且均为非负整数。
叒是一道二分题,这道题跟之前得奶牛类似,先对录取分数进行排序,然后遍历学生的估分,这里就进行二分,找到第一个大于或等于估分的录取分数,用第一大于减估分和第一个大于估分后面哪个是选出一个最小值就行了,如果没有找到第一个大于的话,就用最小值减去就行,废话不多说,上代码。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int n,m,a[100010],b[100010];
ll sum=0;
int main()
{
int k;
cin>>m>>n;
for(int i=0;i<m;i++)
cin>>a[i];
for(int i=0;i<n;i++)
cin>>b[i];
sort(a,a+m);
for(int i=0;i<n;i++)//遍历估分的学生
{
int l=0,r=m-1,mid;
while(l<r)//进行二分
{
mid=(l+r+1)/2;
if(a[mid]<=b[i])
l=mid;
else
r=mid-1;
}
if(a[l]>=b[i])
sum+=a[l]-b[i];
else
sum+=min(abs(a[l]-b[i]),abs(a[l+1]-b[i]));//取绝对值,不然可能出现负数
}
cout <<sum;
return 0;
}
P1401 [入门赛 #18] 禁止在 int 乘 int 时不开 long long
题目描述
在比赛中,根据数据范围,分析清楚变量的取值范围,是非常重要的。int 类型变量与 int 类型变量相乘,往往可能超出 int 类型可以表示的取值范围。
现在,给出两个 int 类型变量 x,y 及其取值范围,请问 x×y 的值是否可能超过 int 类型可以表示的范围?
提示:int 类型可以表示的范围为 [−2147483648,2147483647][−2147483648,2147483647],即 [−231,231−1][−231,231−1]。也就是,int 类型可以表示的最小值为 −2147483648−2147483648,最大值为 21474836472147483647。
输入格式
输入共两行。
输入的第一行为两个整数 xl,xu,表示变量 �x 的取值范围为xl≤x≤xu。
输入的第二行为两个整数 yl,yu,表示变量 �y 的取值范围为 yl≤y≤yu。
输出格式
输出一行一个字符串:
- 若会超过,则输出
long long int
; - 若不会超过,则输出
int
。
输入输出样例
输入 #1复制
1 5 1 5
输出 #1复制
int
输入 #2复制
-2147483647 2147483647 -2147483647 2147483647
输出 #2复制
long long int
说明/提示
数据规模与约定
- 对于 50%50% 的测试数据0≤xl≤xu<231,0≤yl≤yu<231。
- 对于 100%100% 的测试数据,−231≤xl≤xu<231,−231≤yl≤yu<231。
这里判断一下最小值和最小值的乘积,最大值和最大值的乘积以及最大值和最小值的乘积不超过范围就输出int 就行
#include <bits/stdc++.h>
using namespace std;
long long maxx=2147483647;
long long minn=-2147483648;
int main()
{
long long x1,x2,y1,y2;
long long a,b,c,d;
cin>>x1>>x2>>y1>>y2;
a=x1*y1;
b=x2*y2;
c=x1*y2;
d=x2*y1;
if(a>=minn&&a<=maxx&&b>=minn&&b<=maxx&&c>=minn&&c<=maxx&&d>=minn&&d<=maxx)
cout<<"int";
else
cout<<"long long int";
return 0;
}