标签:des style blog http io ar color os sp
本次热身赛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代码
-
#include <iostream>
-
#include <algorithm>
-
#include <cstdio>
-
using namespace std;
-
const int maxn = 1e6+10;
-
struct Node
-
{
-
int x,y;
-
}node[maxn];
-
-
bool cmp(Node a, Node b)
-
{
-
if(a.x == b.x) return a.y < b.y;
-
return a.x < b.x;
-
}
-
int main()
-
{
-
-
int n;
-
while(scanf("%d",&n) != EOF)
-
{
-
int a[1000];
-
for(int i = 0; i < n; i++)
-
{
-
scanf("%d",&a[i]);
-
}
-
int cent = 0;
-
for(int i = 1; i < n; i++)
-
{
-
node[cent].x = a[i-1] < a[i] ? a[i-1] : a[i];
-
node[cent++].y = a[i-1] < a[i] ? a[i] : a[i-1];
-
-
}
-
-
sort(node,node+cent,cmp);
-
int flag = 1;
-
-
for(int i = 0; i < cent; i++)
-
for(int j = 0; j < i; j++)
-
{
-
if( node[i].x == node[j].x && node[i].y >= node[j].y) continue;
-
if(node[i].x < node[j].y && node[i].y > node[j].y)
-
{
-
flag = 0;
-
}
-
}
-
-
if(flag) printf("no\n");
-
else printf("yes\n");
-
}
-
return 0;
-
}
组合 |
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新生赛-热身赛 |
这题用深搜解决,如果不会深搜就理解成不断的递归求解,自己最好拿样例手动在纸上面模拟一下代码就清楚了
-
#include <stdio.h>
-
#include <string.h>
-
-
int a[11];
-
int visit[11];
-
int n,k;
-
void dfs(int d, int q)
-
{
-
if(d == k)
-
{
-
printf("%d",a[0]);
-
for(int i = 1; i < k; i++)
-
printf(" %d",a[i]);
-
printf("\n");
-
return;
-
}
-
-
for(int i = q; i <= n; i++)
-
{
-
if(!visit[i])
-
{
-
visit[i] = 1;
-
a[d] = i;
-
dfs(d+1,i+1);
-
visit[i] = 0;
-
}
-
}
-
}
-
int main()
-
{
-
int T;
-
scanf("%d",&T);
-
while(T--)
-
{
-
memset(a,0,sizeof(a));
-
scanf("%d%d",&n,&k);
-
dfs(0,1);
-
}
-
return 0;
-
}
一个整数的正反面 |
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的奇数位以后的位置)
-
#include <stdio.h>
-
typedef long long LL;
-
int a[65];
-
LL n,k;
-
int main()
-
{
-
while(scanf("%lld%lld",&n,&k) != EOF)
-
{
-
int len = 0,pos = 0,ans,pow;
-
while(n)
-
{
-
a[len++] = n%k;
-
n /= k;
-
}
-
for(int i = len-1; i >= 0; i--)
//我们记录最高不为0的奇数位置
-
{
-
if(i%2 == 1 && a[i] != 0)
-
{
-
pos = i;
-
break;
-
}
-
}
-
-
for(int i = 0; i < pos; i += 2)
//然后把pos之前的偶数位置全部置为k-1
-
{
-
a[i] = k-1;
-
}
-
ans = 0,pow = 1;
-
for(int i = 0; i < len; i += 2)
-
{
-
ans += a[i]*pow;
-
pow *= k;
-
}
-
-
printf("%d\n",ans+1);
-
-
}
-
return 0;
-
}
无聊的小明 |
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]
-
#include <stdio.h>
-
#include <string.h>
-
const int N = 50005;
-
const int mod = 1e9+7;
-
-
int dp[N][2];
-
int main()
-
{
-
int n,a,b;
-
while(scanf("%d%d%d",&n,&a,&b)!=EOF)
-
{
-
memset(dp,0,sizeof(dp));
-
dp[0][1]=1;
-
dp[0][0]=1;
-
for(int i=1;i<=n;i++)
-
{
-
for(int j=1;j<=i&&j<=a;j++)
-
{
-
dp[i][1]+=dp[i-j][0];
-
dp[i][1]%=mod;
-
}
-
for(int j=1;j<=i&&j<=b;j++)
-
{
-
dp[i][0]+=dp[i-j][1];
-
dp[i][0]%=mod;
-
}
-
}
-
printf("%d\n",(dp[n][0]+dp[n][1])%mod);
-
}
-
-
return 0;
-
}
这四个题目分链接地址:
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblemVolume
第一个简单的计算机几何可以A掉,还有就是组合那题也可以递归求出,其它两题有兴趣可以看看
哈理工新生赛热身赛解题报告
标签:des style blog http io ar color os sp
原文地址:http://blog.csdn.net/u013445530/article/details/41650931