ayit大一五五欢乐赛
B HDU - 5703
A tourist gets lost in the desert with n liters of water. He drinks positive integer units of water each day.
Write a program to calculate how many different ways the tourist can drink up the water.
Input
The first line contains the number of test cases T(T≤10) .
Next T lines contain the number n(1≤n≤1000000) for each test case.
Output
Output consists of T lines.
Each line contains the binary number which represents number of different ways to finish up the water specified in the test case.
Sample Input
1
3
Sample Output
100
Hint
3 liters of water can be comsumed in four different ways show in the following.
- 1 1 1
- 1 2
- 2 1
- 3
If we write 4 in binary, it’s 100.
#include<stdio.h>
int main()
{
int t,n,i;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("1");n--;
while((n--)!=0)printf("0");
printf("\n");
}
return 0;
}
思路:
划分有2n-1种可能,又因为要输出二进制,那就可以直接先输出一个1,再输出n-1个0,要是算出结果再转化成二进制的话又慢又麻烦,数据还可能溢出
C HDU - 2050
我们看到过很多直线分割平面的题目,今天的这个题目稍微有些变化,我们要求的是n条折线分割平面的最大数目。比如,一条折线可以将平面分成两部分,两条折线最多可以将平面分成7部分,具体如下所示。
Input
输入数据的第一行是一个整数C,表示测试实例的个数,然后是C 行数据,每行包含一个整数n(0<n<=10000),表示折线的数量。
Output
对于每个测试实例,请输出平面的最大分割数,每个实例的输出占一行。
Sample Input
2
1
2
Sample Output
2
7
#include<stdio.h>
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);n=n*2-1;
printf("%d\n",(n+1)*n/2+1);
}
return 0;
}
思路:
找规律题,先跟根据比折线分割简单的直线分割找起,画图列一些数据,再画图列出折线分割的一些数据,看两组数据有没有关系,很显然,n*2-1条直线分割的最大区块数相当于n条折线分割的最大区块数(直线数n与切割出来的最大区块数m的关系是m=(n+1)*n/2+1)
D CodeForces - 1420A
For god’s sake, you’re boxes with legs! It is literally your only purpose! Walking onto buttons! How can you not do the one thing you were designed for?
Oh, that’s funny, is it? Oh it’s funny? Because we’ve been at this for twelve hours and you haven’t solved it either, so I don’t know why you’re laughing. You’ve got one hour! Solve it!
Wheatley decided to try to make a test chamber. He made a nice test chamber, but there was only one detail absent — cubes.
For completing the chamber Wheatley needs nn cubes. i-th cube has a volume ai.
Wheatley has to place cubes in such a way that they would be sorted in a non-decreasing order by their volume. Formally, for each i>1, ai−1≤ai must hold.
To achieve his goal, Wheatley can exchange two neighbouring cubes. It means that for any i>1 you can exchange cubes on positions i−1 and i.
But there is a problem: Wheatley is very impatient. If Wheatley needs more than n⋅(n−1)/2−1 exchange operations, he won’t do this boring work.
Wheatly wants to know: can cubes be sorted under this conditions?
Input
Each test contains multiple test cases.
The first line contains one positive integer t (1≤t≤1000), denoting the number of test cases. Description of the test cases follows.
The first line of each test case contains one positive integer n (2≤n≤5⋅104) — number of cubes.
The second line contains nn positive integers ai (1≤ai≤109) — volumes of cubes.
It is guaranteed that the sum of nn over all test cases does not exceed 105.
Output
For each test case, print a word in a single line: “YES” (without quotation marks) if the cubes can be sorted and “NO” (without quotation marks) otherwise.
Example
Input
3
5
5 3 2 1 4
6
2 2 2 2 2 2
2
2 1
Output
YES
YES
NO
Note
In the first test case it is possible to sort all the cubes in 7 exchanges.
In the second test case the cubes are already sorted.
In the third test case we can make 0 exchanges, but the cubes are not
sorted yet, so the answer is “NO”.
#include<stdio.h>
long long a[50010];
int main()
{
long long t,n,i;
scanf("%lld",&t);
while(t--)
{
scanf("%lld",&n);
for(i=0;i<n;i++)
scanf("%lld",&a[i]);
for(i=0;i<n-1;i++)
if(a[i]<=a[i+1])
break;
if(i!=n-1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
题目大意:
让非降序排序,只能相邻两个交换,交换次数 <= n⋅(n−1)/2−1输出YES,否则输出NO
思路:
相邻交换排序,这不就是冒泡排序么,冒泡排序最糟糕的情况(给的数据严格降序)要交换的次数就是n⋅(n−1)/2,这样一来就只用判断数据中有任意两个相邻的数据 左边<=右边 交换次数就一定 <= n⋅(n−1)/2−1 输出YES就行,否则输出NO
G HDU - 1869
1967年,美国著名的社会学家斯坦利·米尔格兰姆提出了一个名为“小世界现象(small world phenomenon)”的著名假说,大意是说,任何2个素不相识的人中间最多只隔着6个人,即只用6个人就可以将他们联系在一起,因此他的理论也被称为“六度分离”理论(six degrees of separation)。虽然米尔格兰姆的理论屡屡应验,一直也有很多社会学家对其兴趣浓厚,但是在30多年的时间里,它从来就没有得到过严谨的证明,只是一种带有传奇色彩的假说而已。
Lele对这个理论相当有兴趣,于是,他在HDU里对N个人展开了调查。他已经得到了他们之间的相识关系,现在就请你帮他验证一下“六度分离”是否成立吧。
Input
本题目包含多组测试,请处理到文件结束。
对于每组测试,第一行包含两个整数N,M(0<N<100,0<M<200),分别代表HDU里的人数(这些人分别编成0~N-1号),以及他们之间的关系。
接下来有M行,每行两个整数A,B(0<=A,B<N)表示HDU里编号为A和编号B的人互相认识。
除了这M组关系,其他任意两人之间均不相识。
Output
对于每组测试,如果数据符合“六度分离”理论就在一行里输出"Yes",否则输出"No"。
Sample Input
8 7
0 1
1 2
2 3
3 4
4 5
5 6
6 7
8 8
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 0
Sample Output
Yes
Yes
#include<stdio.h>
#define inf 99999999
int a[210][210];
void init(int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i==j)a[i][j]=0;
else a[i][j]=inf;
}
int main()
{
int i,j,k,n,m,x,y;
while(~scanf("%d%d",&n,&m))
{
init(n);
for(i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
a[y][x]=a[x][y]=1;
}
for(k=0;k<n;k++)
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(a[i][j]>a[i][k]+a[k][j])
a[i][j]=a[i][k]+a[k][j];
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
if(a[i][j]-1>6)//注意此处要减1
{
printf("No\n");
break;
}
if(j!=n)
break;
}
if(i!=n)
continue;
printf("Yes\n");
}
return 0;
}
思路:
数据较小可直接用Floyd-Warshall(弗洛伊德-沃舍尔)算法
H LightOJ - 1282
You are given two integers: n and k, your task is to find the most significant three digits, and least significant three digits of nk.
Input
Input starts with an integer T (≤ 1000), denoting the number of test cases.
Each case starts with a line containing two integers: n (2 ≤ n < 231) and k (1 ≤ k ≤ 107).
Output
For each case, print the case number and the three leading digits (most significant) and three trailing digits (least significant). You can assume that the input is given such that nk contains at least six digits.
Sample Input
5
123456 1
123456 2
2 31
2 32
29 8751919
Sample Output
Case 1: 123 456
Case 2: 152 936
Case 3: 214 648
Case 4: 429 296
Case 5: 665 669
#include<stdio.h>
#include<math.h>
int f;
long long ksm(long long n,long long k)
{
long long sum=1;
while(k)
{
if(!f&&sum*n>=100)f=1;//这里f用来标记结果是否是3位数
if(k&1)sum=sum*n%1000;
n=n*n%1000;k/=2;
}
return sum;
}
int main()
{
long long i,t,n,k,mm,nn;double mi,m;
scanf("%lld",&t);
for(i=1;i<=t;i++)
{
scanf("%lld%lld",&n,&k);f=0;
mi=k*(log10(n)-ceil(log10(n)));//这里后面那个向上向下取整都行,目的是不让mi溢出
mi+=ceil(2-mi);//保证pow(10,mi)小数点前面有三位数
// while(mi<2)mi++; 上面的比这个处理的快
mm=pow(10,mi);
nn=ksm(n,k);
if(!f)mm=nn;//小于三位数时用 快速幂 算出来的结果,对数 算出来的结果比实际大了10或100倍
printf("Case %lld: %03lld %03lld\n",i,mm,nn);
}
return 0;
}
思路:
用对数求前三位,快速幂求后三位
用到的对数公式log10(nk)=k*log10(n)