哈理工新生赛热身赛解题报告

本次热身赛6道题目,由于没有官方解题报告,自己写了一个山寨版的解题报告,希望对学弟学妹有所帮助

期中两到签到题该校OJ上没有挂出,我在田大神的帮助下a掉了其它四题,解题报告如下所示

线段
Time Limit: 1000 MS Memory Limit: 32768 K
Total Submit: 10(6 users) Total Accepted: 7(6 users) Rating:  Special Judge: No
Description

坐标轴上有一些点,依次给出。点与点之间要求用一个半圆的直径连接,即把这两个点作为连接他们的半圆的直径的两个端点。第一个点与第二个点连,第二个与第三个连。半圆不能在坐标轴下面。问最后连出的图形,是否存在两个半圆他们是交叉的。

Input

多组测试数据。

每组测试数据的第一行有一个数n(1 ≤ n ≤ 1000),表示有n个点。

之后一行有n个数x1,?x2,?...,?xn (?-?10^6 ≤ xi ≤ 10^6),每个数表示该点在坐标轴的位置。

Output

如果最后的图形有交叉,输出yes,如果没有,输出no。

Sample Input

4

0 10 5 15

4

0 15 5 10

Sample Output

yes

no

Source
2014.11.29新生赛-热身赛

要考虑多种情况,注意两个半圆有一点重合的地方那种情况就行

然后这题我用c++写的,如果要转化成c,只要把sort()排序函数,自己手写一个就行

就是按照x从小到大排序结构体,如果x1相同,按照从小到大排x2就行

比如数据0 15 5 10

排序后

0 15

5 10

5 15

然后每次往前比较,如有交叉的标记下

AC代码

[cpp] view
plain
copy

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstdio>
  4. using namespace std;
  5. const int maxn = 1e6+10;
  6. struct Node
  7. {
  8. int x,y;
  9. }node[maxn];
  10. bool cmp(Node a, Node b)
  11. {
  12. if(a.x == b.x) return a.y < b.y;
  13. return a.x < b.x;
  14. }
  15. int main()
  16. {
  17. int n;
  18. while(scanf("%d",&n) != EOF)
  19. {
  20. int a[1000];
  21. for(int i = 0; i < n; i++)
  22. {
  23. scanf("%d",&a[i]);
  24. }
  25. int cent = 0;
  26. for(int i = 1; i < n; i++)
  27. {
  28. node[cent].x = a[i-1] < a[i] ? a[i-1] : a[i];
  29. node[cent++].y = a[i-1] < a[i] ? a[i] : a[i-1];
  30. }
  31. sort(node,node+cent,cmp);
  32. int flag = 1;
  33. for(int i = 0; i < cent; i++)
  34. for(int j = 0; j < i; j++)
  35. {
  36. if( node[i].x  == node[j].x && node[i].y >= node[j].y) continue;
  37. if(node[i].x < node[j].y && node[i].y > node[j].y)
  38. {
  39. flag = 0;
  40. }
  41. }
  42. if(flag) printf("no\n");
  43. else printf("yes\n");
  44. }
  45. return 0;
  46. }
组合
Time Limit: 1000 MS Memory Limit: 32768 K
Total Submit: 7(5 users) Total Accepted: 6(5 users) Rating:  Special Judge: No
Description

给出一个正整数N,从集合{1,2,3..N} 中找出所有大小为k的子集, 并按照字典序从小到大输出。

Input

第一行是一个整数T,代表T组测试数据。

接下来T行,每行是两个正整数n(1<=n<=10), k(1<=k<=n)。

Output

对于每组数据按字典序输出所有符合条件的子集。

Sample Input

1

5 3

Sample Output

1 2 3

1 2 4

1 2 5

1 3 4

1 3 5

1 4 5

2 3 4

2 3 5

2 4 5

3 4 5

Source
2014.11.29新生赛-热身赛

这题用深搜解决,如果不会深搜就理解成不断的递归求解,自己最好拿样例手动在纸上面模拟一下代码就清楚了

[cpp] view
plain
copy

  1. #include <stdio.h>
  2. #include <string.h>
  3. int a[11];
  4. int visit[11];
  5. int n,k;
  6. void dfs(int d, int q)
  7. {
  8. if(d == k)
  9. {
  10. printf("%d",a[0]);
  11. for(int i = 1; i < k; i++)
  12. printf(" %d",a[i]);
  13. printf("\n");
  14. return;
  15. }
  16. for(int i = q; i <= n; i++)
  17. {
  18. if(!visit[i])
  19. {
  20. visit[i] = 1;
  21. a[d] = i;
  22. dfs(d+1,i+1);
  23. visit[i] = 0;
  24. }
  25. }
  26. }
  27. int main()
  28. {
  29. int T;
  30. scanf("%d",&T);
  31. while(T--)
  32. {
  33. memset(a,0,sizeof(a));
  34. scanf("%d%d",&n,&k);
  35. dfs(0,1);
  36. }
  37. return 0;
  38. }
一个整数的正反面
Time Limit: 3000 MS Memory Limit: 32768 K
Total Submit: 9(4 users) Total Accepted: 5(4 users) Rating:  Special Judge: No
Description

给定一个整数n,和一个整数k。求比n小的,并且在k进制和 -k进制下表示出来的形式是一样的非负整数的个数,例如:

2 :

3进制下:

2 = 2*(30) , 所以2 用3进制表示的形式是2

-3 进制下:

2 = 2*(-3)0, 所以2 用-3 进制表示的形式是2

所以2 在 3 进制和-3进制下的形式是一样的。

再例如:

7:

3进制下:

7 = 1*(30) + 2*(31), 所以7用3进制表示的形式是21

-3进制下:

7 = 0*(-3)0+2*(-3)1+1*(-3)2,所以7用-3进制表示的形式是120

所以7在3进制和-3进制下的形式不一样。

p

k进制:一个整数序列a0, a1, ..., ap,0 <= ai < |k| 并且 ∑(ai*ki)=x 。

i=0

Input

每组输入包括一行,每行包括两个整数n和k。1 <= n <= 1e15, 2 <= k <= 1000。

Output

每组输出包括一个整数,表示答案。

Sample Input

21 3

21 2

Sample Output

9

8

Hint

第一组满足条件的非负整数:0 1 2 9 10 11 18 19 20

第二组满足条件的非负整数:0 1 4 5 16 17 20 21

Source
2014.11.29新生赛-热身赛

这题是思维题目,要明白当所有的奇数位为0的时候才会满足要求

那如果求个数呢?

举个例子:

比如 101 十进制(n = 101, k = 10)

所有的答案就是 000 001 002 …… 009 100 101

中间那位永远都是零要不然就不是答案

所以去掉中间那位之后

0 1 2 …… 9 10 11 也就是12个

那么我们将101缩成11,那答案就是1*10^0+1*10^1 = 11,但是要加1,因为0也算一个

所以我们只需要求出比n小的数的奇数为置0,偶数为另它为k(注意是最高不为0的奇数位以后的位置)

[cpp] view
plain
copy

  1. #include <stdio.h>
  2. typedef long long  LL;
  3. int a[65];
  4. LL n,k;
  5. int main()
  6. {
  7. while(scanf("%lld%lld",&n,&k) != EOF)
  8. {
  9. int len = 0,pos = 0,ans,pow;
  10. while(n)
  11. {
  12. a[len++] = n%k;
  13. n /= k;
  14. }
  15. for(int i = len-1; i >= 0; i--)
     //我们记录最高不为0的奇数位置
  16. {
  17. if(i%2 == 1 && a[i] != 0)
  18. {
  19. pos = i;
  20. break;
  21. }
  22. }
  23. for(int i = 0; i < pos; i += 2)
     //然后把pos之前的偶数位置全部置为k-1
  24. {
  25. a[i] = k-1;
  26. }
  27. ans = 0,pow = 1;
  28. for(int i = 0; i < len; i += 2)
  29. {
  30. ans += a[i]*pow;
  31. pow *= k;
  32. }
  33. printf("%d\n",ans+1);
  34. }
  35. return 0;
  36. }
无聊的小明
Time Limit: 3000 MS Memory Limit: 32768 K
Total Submit: 4(4 users) Total Accepted: 4(4 users) Rating:  Special Judge: No
Description

小明想用两个字母a和b创造一个长度为n的单词,但是他又不希望连续的a超过p个,同时也不希望连续的b超过q个。那么小明有能创造出多少个不用的单词呢?

Input

每组数据包括一行,三个整数n,p,q分别对应题意。

其中max(a, b) <= n <= 50000,1 <= a, b <= 300。

Output

输出不同的单词的个数。个数要对1000000007取模。

Sample Input

3 2 1

Sample Output

4

Source
2014.11.29新生赛-热身赛

dp[i][j]表示长度为i 结尾数是j 的方案数量

ans[len]=dp[len][0]+dp[len][1](用0,1代替a,b)

状态转移方程:

dp[i][1]+=dp[i-j][0];

dp[i][0]+=dp[i-j][1];

举例子说明:

比如0最多只能连续不超过3个

xxxxxxxxxx10

xxxxxxxxx100

xxxxxxxx1000

这就表示结尾零的可能情况,

最后一个x必须是1

所以 dp[i][0]=dp[i-1][1]+dp[i-2][1]+dp[i-3][1]

[cpp] view
plain
copy

  1. #include <stdio.h>
  2. #include <string.h>
  3. const int N = 50005;
  4. const int mod = 1e9+7;
  5. int dp[N][2];
  6. int main()
  7. {
  8. int n,a,b;
  9. while(scanf("%d%d%d",&n,&a,&b)!=EOF)
  10. {
  11. memset(dp,0,sizeof(dp));
  12. dp[0][1]=1;
  13. dp[0][0]=1;
  14. for(int i=1;i<=n;i++)
  15. {
  16. for(int j=1;j<=i&&j<=a;j++)
  17. {
  18. dp[i][1]+=dp[i-j][0];
  19. dp[i][1]%=mod;
  20. }
  21. for(int j=1;j<=i&&j<=b;j++)
  22. {
  23. dp[i][0]+=dp[i-j][1];
  24. dp[i][0]%=mod;
  25. }
  26. }
  27. printf("%d\n",(dp[n][0]+dp[n][1])%mod);
  28. }
  29. return 0;
  30. }

这四个题目分链接地址:

http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblemVolume

第一个简单的计算机几何可以A掉,还有就是组合那题也可以递归求出,其它两题有兴趣可以看看

时间: 2024-08-05 06:33:18

哈理工新生赛热身赛解题报告的相关文章

2014 UESTC 暑前集训队内赛(1) 解题报告

A.Planting Trees 排序+模拟 常识问题,将耗时排一个序,时间长的先种,每次判断更新最后一天的时间. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define Mod 1000000007 #define INT 2147483647 #define pi acos(-1.0)

CSU-ACM2014暑假集训基础组训练赛(1) 解题报告

•Problem A HDU 4450                 水题,签到题 水题..没啥好说的.给大家签到用的. 1 #include <cstdio> 2 int main(){ 3 int n,a,ans; 4 while(scanf("%d",&n),n){ 5 ans = 0; 6 for(int i = 0;i < n;i++){ 7 scanf("%d",&a); 8 ans += a*a; 9 } 10 pr

CSU-ACM暑假集训基础组训练赛(4)解题报告

•Problem A SPOJ SUB_PROB   AC自动机 •题意: 给定一个长为M(M≤100000 )的文本串,和N(N≤1000)个长度不超过2000的模式串,问每个模式串是否在文本串中出现过? •几乎和周一课件上的第一个例题一模一样.. •把文本串丢到AC自动机里面去跑. •注意: •1.可能有两个相同的模式串(略坑吧.) •2.一个模式串可能是另一个模式串的后缀,即如果一个点的fail指针指向的点是一个“危险节点”,那么它本身也是一个“危险节点”. 1 #include <ios

暑假第二次考试 冲刺Noip2017模拟赛2 解题报告——五十岚芒果酱

题1 牛跑步(running) [题目描述] 新牛到部队,CG 要求它们每天早上搞晨跑,从 A 农场跑到 B 农场.从 A 农场到 B 农场中有 n-2 个路口,分别标上号,A 农场为 1 号,B 农场为 n 号,路口分别为 2...n-1 号,从 A 农场到 B 农场有很多条路径可以到达,而 CG 发现有的路口是必须经过的,即每条路径都经过的路口,CG 要把它们记录下来,这样 CG 就可以先到那个路口,观察新牛们有没有偷懒,而你的任务就是找出所有必经路口. [输入格式] 第一行两个用空格隔开的

CH Round #55 - Streaming #6 (NOIP模拟赛day2)解题报告

T1九九归一 描述 萌蛋在练习模n意义下的乘法时发现,总有一些数,在自乘若干次以后,会变成1.例如n=7,那么5×5 mod 7=4,4×5 mod 7=6,6×5 mod 7=2,2×5 mod 7=3,3×5 mod 7=1.如果继续乘下去,就会陷入循环当中.萌蛋还发现,这个循环的长度经常会是φ(n),即小于n且与n互质的正整数的个数.例如,φ(7)=6,而上述循环的长度也是6,因为5,4,6,2,3,1共有6个数.再如n=6,那么5×5 mod 6=1.这个循环的长度很短,只有2,而恰好φ

暑假第四次考试 冲刺Noip模拟赛4 解题报告——五十岚芒果酱

题1 韬韬抢苹果(apple) [问题描述] 又到了收获的季节,树上结了许多韬韬,错了,是许多苹果,有很多个小韬韬都来摘苹 果.每个韬韬都想要最大的苹果,所以发生了争执,为了解决他们的矛盾,出题人定了一项 特殊的规则,按体重的大小来定顺序,每一轮都是先由胖的先摘(照顾胖子),每个韬韬都 是很聪明的,不会错过眼前最大的苹果.现在问题来了,一共有 n 个苹果,m 个韬韬,要你 按原顺序输出每个韬韬可以抢到的苹果的总大小. [输入格式]apple.in 第一行两个数 n,m. 接下来一行 n 个数,分

冲刺Noip2017模拟赛6 解题报告——五十岚芒果酱

1.ksum(ksum) [问题描述] Peter喜欢玩数组.NOIP这天,他从Jason手里得到了大小为n的一个正整数 数组. Peter求出了这个数组的所有子段和,并将这n(n+1)/2个数降序排序,他想 知道前k个数是什么. [输入格式] 输入文件名为 ksum.in. 输入数据的第一行包含两个整数 n 和 k. 接下来一行包含 n 个正整数,代表数组. [输出格式] 输出文件名为 ksum.out. 输出 k 个数,代表降序之后的前 k 个数,用空格隔开. [输入输出样例] ksum.i

20161022 NOIP模拟赛 T2 解题报告

旅行者问题 [问题描述] lahub是一个旅行者的粉丝,他想成为一个真正的旅行者,所以他计划开始一段旅行.lahub想去参观n个目的地(都在一条直道上).lahub在起点开始他的旅行.第i个目的地和起点的距离为ai千米(ai为非负整数).不存在两个目的地和起点的距离相同. 从第i个目的地走到第j个目的地所走的路程为 |ai-aj|千米.我们把参观n个目的地的顺序称作一次“旅行”.lahub可以参观他想要参观的任意顺序,但是每个目的地有且只能被参观一次(参观顺序为n的排列). lahub把所有可能

CH Round #54 - Streaming #5 (NOIP模拟赛Day1)解题报告

最近参加了很多CH上的比赛呢~Rating--了..题目各种跪烂.各种膜拜大神OTZZZ T1珠 描述 萌蛋有n颗珠子,每一颗珠子都写有一个数字.萌蛋把它们用线串成了环.我们称一个数字串是有趣的,当且仅当它的第1位是2,且除了第1位以外的每一位都是3.例如,2,233,2333333都是有趣的数字串.现在,你可以从这串珠子的任意一颗开始读,沿着顺时针或逆时针方向,到任意一颗珠子停止.这样,你就可以读出一个数字串来.萌蛋想知道,所有能读出的有趣的数字串当中,最长的是哪一个数字串.当然,你也可能读不