紧张刺激的新手赛结束了……有惊无险啊啊啊,虽然中途OJ炸了一次……很快就修复,感谢大家耐心的等待!一开始有的教室环境没装好,也感谢大家耐心的等待下载……毕竟我校第一次除了考试,搞这么大型的ACM比赛……
谢谢大家!!!
题解开始前,先向大家道个歉,题目还是很多误导人的地方,卡的点较多,导致很多人题没过。接下来都会一一解释……希望大家能理解……不过题目区分度还是达到了预期,有的同学表现也很抢眼。
1 2 3
6.00
题目定位:签到题,难度系数 1(满分10分)
题解:保留两位小数。这里是采用直接丢弃两位后面的位……不是四舍五入……JAVA的同学要注意……另外输入的A,B,C有可能是小数!所以要用double 存!不要用int!否则会错!
标程:
#include
using namespace std;
int main(){
double a,b,c;
cin>>a>>b>>c;
printf("%.2lf\n",a+b+c);
return 0;
}
-2
2 3
3 -2
4 4
1 -2.00
题目定位:简单题,难度系数 3
题解:保留两位小数。注意!出现了除法运算!就必须要用double !如果变量用int存,运算完毕后,还是int,这就不对了,我们需要在运算的过程中强制转换为double,或者直接用double来保存变量。其他的,自己思考怎么实现了,毕竟行列式公式也给了,剩下的就是逻辑问题。具体看代码。
标程:
#include
using namespace std;
int main(){
double K;
double zs,zx,ys,yx;
int a=0,b=0,c=0;
int weizhi=10;
cin>>a;
if(a==1)cin>>zs;
if(a==2)cin>>ys;
if(a==3)cin>>zx;
if(a==4)cin>>yx;
cin>>b;
if(b==1)cin>>zs;
if(b==2)cin>>ys;
if(b==3)cin>>zx;
if(b==4)cin>>yx;
cin>>c;
if(c==1)cin>>zs;
if(c==2)cin>>ys;
if(c==3)cin>>zx;
if(c==4)cin>>yx;
weizhi-=a+b+c;
if(weizhi==1){
zs=(K+zx*ys)/yx;
printf("%d %.2lf\n",weizhi,zs);
}
if(weizhi==2){
ys=(zs*yx-K)/zx;
printf("%d %.2lf\n",weizhi,ys);
}
if(weizhi==3){
zx=(zs*yx-K)/ys;
printf("%d %.2lf\n",weizhi,zx);
}
if(weizhi==4){
yx=(K+zx*ys)/zs;
printf("%d %.2lf\n",weizhi,yx);
}
//cout<
0 0 10
3
10 0
0 10
10 10
2
数据范围较大
请使用 double或long long int
long int 为32位
long long int 为64位
题目定位:简单题2,难度系数 3
题解:……直接求点到圆心的距离,看看是不是小于R即可~这里没想到卡住了那么多人。首先,int * int会爆int,所以我们要强制转换成long long去运算。比如 100000*100000=100000000000(已经超过了int的范围,实际上不是这个值)。如果还不能理解,请复习C++基础……另外如果用double去运算会失去精度,因为计算机的浮点数运算是有误差的。比如你觉得 6==6,但其实不一定,可能是 6.000001!=6。为了避免精度问题,我们不能使用系统的开方函数。sqrt返回的是double,参数也是double,所以传long long 的话也有可能会失去精度,所以最好的做法,就是直接用long long去运算。详细看代码。
标程:
#include
#include
#include
#include
#include
Input1:
5
1
2
3
4
5
Input2:
3
10000000
10000000
10000000
Output1:
1
Output2:
3
5
1
2
3
4
5
1
题目定位:简单题里面的难题,难度系数 4
题解:这道题开始就考思维了。想到的话,这道题就很简单了。实际上就是求一堆数里的众数的大小!……为什么呢?因为求的是最坏情况,所以肯定是次小的吃掉最小的,然然然后次次小的,吃掉次小的,这样贪心的去吃。你会发现,最后剩下的,就是众数的大小。相当于不同的鱼之间,可以合体,这里的思维很巧妙…自己写多几组样例应该能推出来。标程用了高级的数据结构,实际上这里可以用排序或者结构体去做。
标程:
#include
#include
5
-1 1
-3 1
0 1
7 1
9 1
20
注意数据范围!请使用long long int!
题目定位:难题,难度系数 9
题解:嗯,就一个大佬做出来,不知道为什么这么多人死磕这道题,其实还有很多简单题的……但这道题并不是最难的,这告诉我们,不要盲目跟榜。高难度的思维题,注意分析时间复杂度。
考虑暴力,复杂度O(n^2)明显不可行
第一种思路
在x轴上从左到右枚举,先暴力算出第一个点到所有点的带权距离之和,而后每一个点到其他所有点的带权距离可由前一个点的距离推出
复杂度为O(nlogn+n);
第二种思路
权值可以考虑成有w[i]个这样的点在X轴上,求最中心那个点到所有点的距离之和
注意int类型会溢出,请使用long long。
标程:
#include
#define ll long long
using namespace std;
const int MAX_N=1e4+10;
struct Node
{
int x,w;
}node[MAX_N];
bool cmp(Node a,Node b)
{
return a.x==b.x?a.w<=b.w:a.x
1
1 100
XXgg is Hide On 1
题目定位:中等题,难度系数 6
题解:数据很小,怎么做都行,重点是能不能想出怎么做……题目描述有点小问题(到底谁抓谁?),比赛时没人问,不过不影响做题……这道题默认排好序,不过不影响做题……
数据量只有100 ,暴力可行,找出所有线段的相交点可以使用枚举来实现O(n^2)复杂度可以接受
考虑优化,可以对存储l,r值的结构体进行按l的值从小到大,假如l相等则r从小到大进行排序,之后看是否所有r都小于或等于node【0】.l;复杂度O(logn)
对于此类问题可以用前缀和进行进一步优化,对与每一对l,r,使a[l]=a[l]+1,a[r+1]=a[r]-1;然后通过a[i]+=a[i-1]求出每个点被覆盖了多少次,假如a[i]==n则i满足条件;
标程:
#include
using namespace std;
const int MAX_N=105;
int n,l,r,a[MAX_N];
int main()
{
memset(a,0,sizeof(a));
scanf("%d",&n);
for(int i=0;i0)
for(int i=1;i<=100;i++)
{
a[i]+=a[i-1];
if(a[i]==n)
{
printf("XXgg is Hide On %d\n",i);
return 0;
}
}
puts("XXgg is Hide On Bush");
return 0;
}
输入样例1:
6 1 1 1 0
2 3 1 5 3 2
2 1 2
3 3 4 5
1 6
输入样例 2:
3 2 2 1 1
2 3 2
1 1
1 2
1 2
1 3
1 1
2 3
输入样例3:
3 1 1 1 1
5 5 5
3 1 2 3
3 1 2 3
3 1 2 3
2 1
输出样例1:
180
输出样例 2:
22
输出样例3:
0
3 2 2 1 1
2 3 2
1 1
1 2
1 2
1 3
1 1
2 3
22
题目定位:中等题中的简单题,难度系数 5
题解:这道题让我很意外……因为……这是一道简单题啊……现场竟然只有一个交,而且还是绝杀!只是描述很长,让大家感觉是难题……但相信我,真的是简单题……处理的时候,循环比较多而已。原题是一道英文题,而且数据很大,卡了long double的精度。这里把数据范围缩小到10以内。随便做都可以。
原题链接:http://blog.csdn.net/lzc504603913/article/details/78185185
怎么做呢?答案就是,把所有用到的调料的牌子数相乘即可!!中间注意要把不能一起吃的菜排除,这里用二维数组记录即可!还有出现过相同的调料,直接把牌子数变成1或者不乘即可!这里标程用set去做了。
权哥的代码:
#include
#include
#include
using namespace std;
int main()
{
int R,S,M,D,N,i,j,k;
long long s[15][15],m[15][15],d[15][15],b[15];
bool tr[105][105];
cin >> R >> S>>M>>D>>N;
for (i=1;i<=R;i++)
{
cin >> b[i];
}
long long ans=0;
for (i=1;i<=S;i++)
{
cin >> s[i][0];
for (j=1;j<=s[i][0];j++)
{
cin >> s[i][j];
}
}
for (i=1;i<=M;i++)
{
cin >> m[i][0];
for (j=1;j<=m[i][0];j++)
{
cin >> m[i][j];
}
}
for (i=1;i<=D;i++)
{
cin >> d[i][0];
for (j=1;j<=d[i][0];j++)
{
cin >> d[i][j];
}
}
memset(tr,true,sizeof(tr));
for (i=1;i<=N;i++)
{
cin >> j >> k;
tr[j][k]=false;
tr[k][j]=false;
}
int i1,i2,i3,er;
bool w;
bool t[15];
ans=0;
for (i1=1;i1<=S;i1++)
for (i2=1;i2<=M;i2++)
for (i3=1;i3<=D;i3++)
{
memset (t,false,sizeof(t));
if (tr[i1][i2+S]&&tr[i1][i3+S+M]&&tr[i2+S][i3+M+S])
{
for (i=1;i<=s[i1][0];i++)
t[s[i1][i]]=true;
for (i=1;i<=m[i2][0];i++)
t[m[i2][i]]=true;
for (i=1;i<=d[i3][0];i++)
t[d[i3][i]]=true;
er=1;
w=false;
for (i=1;i<=R;i++)
if (t[i])
{
er*=b[i];
w=true;
}
if (w)
ans+=er;
}
}
cout << ans;
}
#include
#include
#include
#include
#include
输入样例1:
5 1 1 1 4 0 5
1 1
2 1
3 1
4 0
5 0
输入样例2:
1 1 2 1 2 1 2
1 0
输入样例3:
10 1 1 1 2 0 10
1 1
2 1
3 0
4 0
5 1
6 1
7 1
8 1
9 1
10 1
输出样例1:
6
输出样例2:
-1
输出样例3:
5
10 1 1 1 2 0 10
1 1
2 1
3 0
4 0
5 1
6 1
7 1
8 1
9 1
10 1
5
题目定位:防AK题,即最难题,难度系数 10
题解:这道题真防AK……但是还是没有考算法……还是考思维,这题很容易让人陷入二分,然后会调半天,二分应该是不能做的,至少我没有用二分做出来。最后用了尺取法,尺取法是一种思维的方法,可以大大降低复杂度。详细看原题的解释……
原题链接:http://blog.csdn.net/lzc504603913/article/details/78481915
标程:
#include
#include
#include
#include
#include
如输入
200
输出
NOT FOUND
1
2
题目定位:中等题里的简单题,难度系数 6
题解:考察了质数的概念,这里数据范围很小,O(N^2)筛选质数也是可以的~!其他的就是读题啦!!很多人没搞懂提议,所以没做出来。这里还是自己想懂比较好。
标程:
#include
using namespace std;
const int MAX_N=1005;
int a[MAX_N],cnt=0,k;
bool is_prime[MAX_N];
void seive()
{
fill(is_prime,is_prime+MAX_N,true);
for(int i=2;icnt)
{
puts("NOT FOUND");
}
else
{
printf("%d\n",a[k-1]);
}
return 0;
}
最后!谢谢阅读!ACM还是很有趣滴~!希望大家能坚持下去!收获满满的~!