简单的做一下总结,还算比较适应,题目也很契合学的内容,总之是一场不错的比赛
A - Maximum GCD UVA - 11827
Given the N integers, you have to find the maximum GCD (greatest common divisor) of every possible
pair of these integers.
Input
The first line of input is an integer N (1 < N < 100) that determines the number of test cases.
The following N lines are the N test cases. Each test case contains M (1 < M < 100) positive
integers that you have to find the maximum of GCD.
Output
For each test case show the maximum GCD of every possible pair.
Sample Input
3
10 20 30 40
7 5 12
125 15 25
Sample Output
20
1
25
呵!题目,这题一看就很水啦,交了8发,WA的一声哭出来,后来才明白原来是可以多个空格连续输入,为时不晚,A了,就是罚时太多了。
#include
#include
int gcd(int a,int b){
int temp = a%b;
while(temp){
a=b;
b=temp;
temp=a%b;
}
return b;
}
int maxx(int a, int b){
if(a>b)
return a;
else
return b;
}
int main()
{
int n;
scanf("%d",&n);
getchar();
while(n--){
char a[10000];
int b[1000];
gets(a);
int length=0;
for(int i=0;i<strlen(a);i++){
int sum=0;
while(i<strlen(a)&&a[i]!=' '){
sum=sum*10+a[i]-'0';
i++;
}
b[length++]=sum;
}
int ans=0;
for(int i=0;i<length;i++){
for(int j=i+1;j<length;j++){
ans=maxx(ans,gcd(b[i],b[j]));
}
}
printf("%d\n",ans);
}
return 0;
}
C - Subset sequence HDU - 2062
Consider the aggregate An= { 1, 2, …, n }. For example, A1={1}, A3={1,2,3}. A subset sequence is defined as a array of a non-empty subset. Sort all the subset sequece of An in lexicography order. Your task is to find the m-th one.
Input
The input contains several test cases. Each test case consists of two numbers n and m ( 0< n<= 20, 0< m<= the total number of the subset sequence of An ).
Output
For each test case, you should output the m-th subset sequence of An in one line.
Sample Input
1 1
2 1
2 2
2 3
2 4
3 10
Sample Output
1
1
1 2
2
2 1
2 3 1
这道题大体意思就是给你一个数字n,从1到n一共有特定数量的排列,然后输出第m组的排列是什么举例,n为三的时候有排列{1}、{1, 2}、{1, 2, 3}、{1, 3}、{1, 3, 2}、{2}、{2, 1}、{2, 1, 3}、{2, 3}、{2, 3, 1}、{3}、{3, 1}、{3, 1, 2}、{3, 2}、{3, 2, 1}
m=10则输出2 3 1
看懂了之后倒腾了半天公式,n给定后,n个数字有f(n) = n[f(n-1) + 1]个排列,共分为n组
用3 10举例
按照公式,这组有15个组合,每组有5个
我要找的是第10个组合,所以在第二组中
所以第一位是2
之后我去掉所有组合的第一位数字,的到另一个组合,这个组合一共有15-3 = 12个
每组有两个,10这个位置变为8这个位置
所以第二位是3
步骤同上,得到另一个组合,我要找的位置是10-2-4=4
输出1
最终结果为2 3 1
没注意“0< m<= the total number of the subset sequence of An”这一句int爆了,用long long 过了
#include
long long a[30];
long long b[30]={0};
int main(){
for(long long i=0; i<30; i++){
a[i] = i;
}
for(long long i=1; i<30; i++){
b[i] = b[i-1]*(i-1) + 1;
}
long long n,m;
while(~scanf("%lld%lld",&n,&m)){
for(long long i=0; i<30; i++){
a[i] = i;
}
while(n && m){
long long temp = m/b[n]+1;
if(m%b[n] == 0){
temp--;
}
if(temp){
printf("%lld",a[temp]);
for(long long i=temp; i<=n; i++){
a[i] = a[i+1];
}
}
m-=(temp-1)*b[n]+1;
if(m == 0){
printf("\n");
}
else{
printf(" ");
}
n--;
}
}
return 0;
}
D - Big Number HDU - 1212
As we know, Big Number is always troublesome. But it’s really important in our ACM. And today, your task is to write a program to calculate A mod B.
To make the problem easier, I promise that B will be smaller than 100000.
Is it too hard? No, I work it out in 10 minutes, and my program contains less than 25 lines.
Input
The input contains several test cases. Each test case consists of two positive integers A and B. The length of A will not exceed 1000, and B will be smaller than 100000. Process to the end of file.
Output
For each test case, you have to ouput the result of A mod B.
Sample Input
2 3
12 7
152455856554521 3250
Sample Output
2
5
1521
不多说,Java大数模板
import java.util.*;
import java.math.*;
public class Main{
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
while(cin.hasNext())
{
BigInteger a,b;
a=cin.nextBigInteger();
b=cin.nextBigInteger();
System.out.println(a.remainder(b));
}
}
}
E - N!Again HDU - 2674
WhereIsHeroFrom: Zty, what are you doing ?
Zty: I want to calculate N!..
WhereIsHeroFrom: So easy! How big N is ?
Zty: 1 <=N <=1000000000000000000000000000000000000000000000…
WhereIsHeroFrom: Oh! You must be crazy! Are you Fa Shao?
Zty: No. I haven’s finished my saying. I just said I want to calculate N! mod 2009
Hint : 0! = 1, N! = N*(N-1)!
Input
Each line will contain one integer N(0 <= N<=10^9). Process to end of file.
Output
For each case, output N! mod 2009
Sample Input
4
5
Sample Output
24
120
由于是阶乘,所以找出2009所有的因子,发现暴力跑到41就可以了,41之后所有数字的阶乘都是x*2009,所以41之后的数字都输出0;
#include
int main(){
long n;
while(~scanf("%ld",&n)){
if(n >= 41){
printf("0\n");
}
else{
long ans=1;
for(int i=1; i<=n; i++){
ans*=i;
ans%=2009;
}
printf("%ld\n",ans);
}
}
return 0;
}
H - Tickets HDU - 1260
Jesus, what a great movie! Thousands of people are rushing to the cinema. However, this is really a tuff time for Joe who sells the film tickets. He is wandering when could he go back home as early as possible.
A good approach, reducing the total time of tickets selling, is let adjacent people buy tickets together. As the restriction of the Ticket Seller Machine, Joe can sell a single ticket or two adjacent tickets at a time.
Since you are the great JESUS, you know exactly how much time needed for every person to buy a single ticket or two tickets for him/her. Could you so kind to tell poor Joe at what time could he go back home as early as possible? If so, I guess Joe would full of appreciation for your help.
Input
There are N(1<=N<=10) different scenarios, each scenario consists of 3 lines: 1) An integer K(1<=K<=2000) representing the total number of people; 2) K integer numbers(0s<=Si<=25s) representing the time consumed to buy a ticket for each person; 3) (K-1) integer numbers(0s<=Di<=50s) representing the time needed for two adjacent people to buy two tickets together.
Output
For every scenario, please tell Joe at what time could he go back home as early as possible. Every day Joe started his work at 08:00:00 am. The format of time is HH:MM:SS am|pm.
Sample Input
2
2
20 25
40
1
8
Sample Output
08:00:40 am
08:00:08 am
简单的动态规划,就看两个人分别买票和单独买票谁更快一些,取小的
递推公式:c[i] = min(c[i-2] + b[i], c[i-1] + a[i])
#include
int min(int a, int b){
if(a<b)
return a;
return b;
}
int main(){
int N;
scanf("%d",&N);
while(N--){
int first[2005],second[2005];
int ans[2005];
int people,hour,mints,seco;
scanf("%d",&people);
for(int i=0; i<people; i++){
scanf("%d",&first[i]);
}
for(int i=0; i<people-1; i++){
scanf("%d",&second[i]);
}
ans[0] = 0;
ans[1] = first[0];
for(int i=2; i<=people; i++){
ans[i] = min(ans[i-1]+first[i-1],ans[i-2]+second[i-2]);
}
hour = 8+ans[people-1]/3600;
mints = (ans[people]/60)%60;
seco = ans[people]%60;
printf("%02d:%02d:%02d am\n",hour,mints,seco);
}
return 0;
}
I - Filthy Rich HDU - 2391
They say that in Phrygia, the streets are paved with gold. You’re currently on vacation in Phrygia, and to your astonishment you discover that this is to be taken literally: small heaps of gold are distributed throughout the city. On a certain day, the Phrygians even allow all the tourists to collect as much gold as they can in a limited rectangular area. As it happens, this day is tomorrow, and you decide to become filthy rich on this day. All the other tourists decided the same however, so it’s going to get crowded. Thus, you only have one chance to cross the field. What is the best way to do so?
Given a rectangular map and amounts of gold on every field, determine the maximum amount of gold you can collect when starting in the upper left corner of the map and moving to the adjacent field in the east, south, or south-east in each step, until you end up in the lower right corner.
Input
The input starts with a line containing a single integer, the number of test cases.
Each test case starts with a line, containing the two integers r and c, separated by a space (1 <= r, c <= 1000). This line is followed by r rows, each containing c many integers, separated by a space. These integers tell you how much gold is on each field. The amount of gold never negative.
The maximum amount of gold will always fit in an int.
Output
For each test case, write a line containing “Scenario #i:”, where i is the number of the test case, followed by a line containing the maximum amount of gold you can collect in this test case. Finish each test case with an empty line.
Sample Input
1
3 4
1 10 8 8
0 0 1 8
0 27 0 4
Sample Output
Scenario #1:
42
简单动态规划,取价值高的进行计算
状态转移方程:dp[j] = max(dp[j-1],dp[j])+ Map[i][j]
#include
using namespace std;
int map0[1005][1005]={0};
int map1[1005][1005]={0};
int main(){
int N;
int t;
scanf("%d",&N);
t = N;
while(N--){
int x,y;
scanf("%d%d",&x,&y);
for(int i=1; i<=x; i++){
for(int j=1; j<=y; j++){
scanf("%d",&map0[i][j]);
}
}
for(int i=1; i<=x; i++){
for(int j=1; j<=y; j++){
if(map1[i][j-1] >= map1[i-1][j]){
map1[i][j] = map1[i][j-1]+map0[i][j];
}
else{
map1[i][j] = map1[i-1][j]+map0[i][j];
}
}
}
printf("Scenario #%d:\n%d\n\n",t-N,map1[x][y]);
}
return 0;
}
J - Herding HDU - 4709
Little John is herding his father’s cattles. As a lazy boy, he cannot tolerate chasing the cattles all the time to avoid unnecessary omission. Luckily, he notice that there were N trees in the meadow numbered from 1 to N, and calculated their cartesian coordinates (Xi, Yi). To herding his cattles safely, the easiest way is to connect some of the trees (with different numbers, of course) with fences, and the close region they formed would be herding area. Little John wants the area of this region to be as small as possible, and it could not be zero, of course.
Input
The first line contains the number of test cases T( T<=25 ). Following lines are the scenarios of each test case.
The first line of each test case contains one integer N( 1<=N<=100 ). The following N lines describe the coordinates of the trees. Each of these lines will contain two float numbers Xi and Yi( -1000<=Xi, Yi<=1000 ) representing the coordinates of the corresponding tree. The coordinates of the trees will not coincide with each other.
Output
For each test case, please output one number rounded to 2 digits after the decimal point representing the area of the smallest region. Or output “Impossible”(without quotations), if it do not exists such a region.
Sample Input
1
4
-1.00 0.00
0.00 -3.00
2.00 0.00
2.00 2.00
Sample Output
2.00
这个题。。。暴力跑不会超时的,但是需要注意精度的控制,题目说精确到0.01,很有可能三角形的面积为0.001,这时候你存下来,输出是0,你就错了,没考虑到这一点,wa了一次
#include
struct Point{
double x;
double y;
}point[105];
int main(){
int N;
scanf("%d",&N);
while(N--){
int n, flag1 = 1;
double ans = 100000000.0;
scanf("%d",&n);
for(int i=0; i<n; i++){
scanf("%lf%lf",&point[i].x, &point[i].y);
}
for(int i=0; i<n-2; i++){
for(int j=i+1; j<n-1; j++){
for(int k=j+1; k<n; k++){
double temp = ((point[i].x-point[k].x)*(point[j].y-point[k].y) - (point[j].x-point[k].x)*(point[i].y-point[k].y));
if(temp<0)
temp=-temp;
if(temp<0.01)
continue;
if(ans > temp*(1.0/2)){
ans = temp*(1.0/2);
}
flag1 = 0;
}
}
}
if(flag1 == 1){
printf("Impossible\n");
continue;
}
printf("%.2lf\n",ans);
}
return 0;
}