神奇的Noip模拟试题第一试 合理种植 枚举+技巧

1.合理种植

(plant.pas/.c/.cpp)

【问题描述】

大COS在氯铯石料场干了半年,受尽了劳苦,终于决定辞职。他来到表弟小cos的寒树中学,找到方克顺校长,希望寻个活干。

于是他如愿以偿接到了一个任务……

美丽寒树中学种有许多寒树。方克顺希望校园无论从什么角度看都是满眼寒树,因此他不希望有三棵甚至更多寒树种在一条直线上。现在他把校园里n棵寒树的坐标都给了大COS,让他数出存在多少多树共线情况。(若一条直线上有三棵或以上的树,则算出现一个多树共线情况。)

【输入】

输入文件名为plant.in。

第1行一个正整数n,表示寒树棵数。

接下来n行,每行两个非负整数x、y,表示一颗寒树的坐标。没有两颗寒树在同一位置。

【输出】

输出文件名为plant.out。

输出一个整数,表示存在多少多树共线情况。

【输入输出样例】


plant.in


plant.out


6

0 0

1 1

2 2

3 3

0 1

1 0


1

【数据范围】

对于30%的数据,有n≤10;

对于50%的数据,有n≤100;

对于100%的数据,有n≤1,000,0≤x,y≤10,000。

解题报告

  考试的时候花了整整一个小时在纠结这道题上,结果还是没做出来,可能是因为我考虑的太多,不知道怎么标记判重,它的斜率从+10000~-10000,也不好记,又怕超时,就放弃了。结果这道题就是用斜率解的..(啊,无语=-=)。老师给的标程还没有理解,先记在这里有一笔。

  同学提出了一种更容易理解的方法。先求出两两之间的斜率,但是注意要用long long ki=(y1-y2)*100000000LL/(x1-x2) 记录斜率,这样可以避免小数和double 判重的情况,然后枚举每三个点,如果任意两点之间k 相等,则三点共线。特殊处理:x1=x2的情况,斜率此时不存在,所以把它直接赋值为k=1,对后面的也不影响。那么,问题就到了记录判重的身上了。

 定义一个数组used[1005][1005],如果共线三点中used[i][j]=used[i][k]=used[j][k]=true;  也许你就要问了,你只记录了三个点,如果有第4、5、6...个点都共线,不就不能判断了吗?但是,这样想,我们每次都按顺序枚举,如先开始used[1][2]=used[2][3]=used[1][3]=true了,那第四个点一定有

used[1][2]=used[1][4]=used[2][4]=true,依次类推,因为它们具有传递性,所以,所有这条线上的点都会被标记。这样一来就好办了。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int n;
 5 struct pp{
 6     int x, y;
 7 };
 8 pp tree[1005];
 9 bool used[1005][1005]={false};
10 long long ki[1005][1005],ans;
11 int main()
12 {
13     freopen("plant.in","r",stdin);
14     freopen("plant.out","w",stdout);
15     scanf("%d",&n);
16     for (int i=1;i<=n;i++)
17      scanf("%d%d",&tree[i].x,&tree[i].y);
18     for (int i=1;i<=n;i++)
19      for (int j=1;j<=n;j++)
20       if (i!=j)
21       {
22           if (tree[i].x!=tree[j].x) ki[i][j]=(tree[i].y-tree[j].y)*100000000LL/(tree[i].x-tree[j].x);
23           else ki[i][j]=1;
24       }
25     for (int i=1;i<=n-2;i++)
26       for (int j=i+1;j<=n-1;j++)
27         for (int t=j+1;t<=n;t++)
28          if (ki[i][j]==ki[j][t])//!!! ==
29          {
30              if (used[i][j]||used[i][t]||used[j][t])
31                  used[i][j]=used[i][t]=used[j][t]=true;
32              else
33              {
34                  ans++;
35                  used[i][j]=used[i][t]=used[j][t]=true;
36              }
37          }
38     printf("%lld",ans);//long long "%lld"
39     return 0;
40 }

注意细节

时间: 2024-12-15 01:47:14

神奇的Noip模拟试题第一试 合理种植 枚举+技巧的相关文章

神奇的Noip模拟试题一试 2 排队

2 排队 (lineup.pas/.c/.cpp) [问题描述] 小sin所在的班有n名同学,正准备排成一列纵队,但他们不想按身高从矮到高排,那样太单调,太没个性.他们希望恰好有k对同学是高的在前,矮的在后,其余都是矮的在前,高的在后.如当n=5,k=3时,假设5人从矮到高分别标为1.2.3.4.5,则(1,5,2,3,4).(2,3,1,5,4).(3,1,4,2,5)都是可行的排法.小sin想知道总共有多少种可行排法. [输入] 输入文件名为lineup.in. 一行两个整数n和k,意义见问

【数论+技巧】神奇的Noip模拟试题第二试 T1 素数统计

1.      素数统计 (pcount.pas/.c/.cpp) [问题描述] 小tan的老师揣谙戈给同学们布置了一道题,要求统计给定区间内素数的个数.“这不是很简单吗?”小tan忍不住说.揣谙戈冷笑一下说:“等你们看到题目就知道了.”便转身离去. 果然,小tan被那极大的区间吓怕了,现在是你拯救她的时候. [输入] 输入文件名为pcount.in. 输入一行两个正整数a和b,表示给定区间为[a,b]. [输出] 输出文件名为pcount.out. 输出一个整数,表示区间内素数数量. [输入输

10.3 noip模拟试题

希望[题目描述]网页浏览器者有后退与前进按钮,一种实现这两个功能的方式是用两个栈,“前进栈”.“后退栈”.这里你需要实现以下几个功能:BACK: 如果“后退栈”为空则忽略此命令. 否则将当前两面压入“前进栈”,从“后退栈”中取出栈顶页面,并设置为当前页面.FORWARD: 如果“前进栈”为空则忽略此命令.否则将当前两面压入“后退栈”,从“前进栈”中取出栈顶页面,并设置为当前页面.VISIT: 将当前页面压入“后退栈”. 并将当前页面置为指定页面, 并将“前进栈”置空.QUIT: 退出.假设此浏览

9.26 noip模拟试题

魔术球问题弱化版(ball.c/.cpp/.pas) 题目描述 假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,…的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何 2 个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在 n 根柱子上最多能放多少个球.例如,在 4 根柱子上最多可放 11 个球. 对于给定的 n,计算在 n 根柱子上最多能放多少个球. 输入描述 第 1 行有 1 个正整数 n,表示柱子数. 输出描述 一行表示可以放的

10.7 noip模拟试题

楼[问题背景]zhx 为他的妹子造了一幢摩天楼.[问题描述]zhx 有一幢摩天楼. 摩天楼上面有 M 个观光电梯,每个观光电梯被两个整数???? " ,???? " 描述.每个电梯只有两个按钮, (针对第 i 个电梯)两个按钮分别可以使电梯向上???? " 层向下???? " 层.摩天楼的高度是无限的,但是电梯不可以钻入地下,也就是说是有下限的.每层楼用整数标记, 以 0 作为地面这一层的标记.zhx 去陪他妹子了,留你一个人在摩天楼的 0 层,现在你想知道,仅可以

10.27 noip模拟试题(afternoon)(跪在游戏玩少了2333)

[问题描述] 祖玛是一款曾经风靡全球的游戏,其玩法是:在一条轨道上初始排列着若干个彩色珠子,其中任意三个相邻的珠子不会完全同色.此后,你可以发射珠子到轨道上并加入原有序列中.一旦有三个或更多同色的珠子变成相邻,它们就会立即消失.这类消除现象可能会连锁式发生,其间你将暂时不能发射珠子. 开发商最近准备为玩家写一个游戏过程的回放工具.他们已经在游戏内完成了过程记录的功能,而回放功能的实现则委托你来完成. 游戏过程的记录中,首先是轨道上初始的珠子序列,然后是玩家接下来所做的一系列操作.你的任务是,在各

10.4 noip模拟试题

题目名称 PA 青春 三部曲 名称 huakai taritari truetears 输入 huakai.in taritari.in truetears.in 输出 huakai.out taritari.out truetears.out 每个测试点时限 1秒 1秒 1秒 内存限制 512MB 512MB 512MB 测试点数目 10 10 10 每个测试点分值 10 10 10 是否有部分分 无 无 无 题目类型 传统 传统 传统 注意事项(请务必仔细阅读): PA [题目描述] 汉诺塔

10.27 noip模拟试题(moring)

WPS转word太丑了 凑合看喽 第二题 [题目描述] 给你两个日期,问这两个日期差了多少毫秒. [输入格式] 两行,每行一个日期,日期格式保证为“YYYY-MM-DD hh:mm:ss ”这种形式.第二个日期时间一定比第一个日期时间要大两个日期的年份一定都是 21 世纪的年份. [输出格式] 一行一个整数代表毫秒数. [样例输入 1] 2000-01-01 00:00:00 2000-01-01 00:00:01 [样例输出 1] 1000 [样例输入 2] 0 1 2 3 4 5 6 7 8

9.30 noip模拟试题

时限均为1s,内存 256MB 1.某种密码(password.*) 关于某种密码有如下描述:某种密码的原文A是由N个数字组成,而密文B是一个长度为N的01数串,原文和密文的关联在于一个钥匙码KEY.若KEY=∑?[Ai*Bi],则密文就是原文的一组合法密码. 现在有原文和钥匙码,请编一个程序来帮助他统计到底有多少个符合条件的密文. [输入数据] 第一行两个数N,KEY,意义同题目描述: 第二行N个数表示原文A,意义同题目描述. [输出数据] 一个数ANS,表示对于原文A和KEY,有多少组可行的