第一次acm练习(排序,预处理)

第一次acm练习总结

1001 最小公倍数

###Problem Description
给定两个正整数,计算这两个数的最小公倍数。
###Input
输入包含多组测试数据,每组只有一行,包括两个不大于1000的正整数.
###Output
对于每个测试用例,给出这两个数的最小公倍数,每个实例输出一行。

Sample Input

10 14  

Sample Output

70  

Source

POJ

个人理解

建立变量sum为两个值的乘积
从两个数中大的数开始向下遍历,若是可以被两个数同时整除,将sum和两个数同时除以该数
当该数减到零的时候结束循环

代码实现

#include<stdio.h>  
int main()   
{  
    int a,b;  
    while(scanf("%d%d",&a,&b)==2){   
        int ha,hb,sum=0,max;
        if(a==b){
            sum=a;
        }
        else{
            ha=a/2;   //找两个数中较大的数的一半
            hb=b/2;
            if(ha>hb){
                max=ha;
            }
            else{
                max=hb;
            }
            sum=a*b;
            for(int i=max;i>0;i--){   //遍历到一半即可
                if(a%i==0&&b%i==0){
                    sum=sum/i;
                    a=a/i;
                    b=b/i;
                }
            }
        } 
        printf("%d\n",sum);
    }
    return 0;
}

1002 人见人爱A^B

Problem Description

求A^B的最后三位数表示的整数。
说明:A^B的含义是“A的B次方”

Input

输入数据包含多个测试实例,每个实例占一行,由两个正整数A和B组成(1<=A,B<=10000),如果A=0, B=0,则表示输入数据的结束,不做处理。

Output

对于每个测试实例,请输出A^B的最后三位表示的整数,每个输出占一行。

Sample Input

2 3
12 6
6789 10000
0 0

Sample Output

8
984
1

Author

lcy

Source

ACM程序设计期末考试(2006/06/07)

个人理解

每次进行相乘的时候都对1000取余数就不会超出运算时间

代码实现

#include<stdio.h>
int main(){
    int a,b;
    while(scanf("%d%d",&a,&b)==2){
        if(a==0&&b==0)
            break;
        a=a%1000;
        int i=0,sum=a;
        for(i=1;i<b;i++){
            sum=sum*a;
            if(sum>1000){
                sum=sum%1000;
            }
        }
        printf("%d\n",sum);
    }    
    return 0;
}

1003 Rightmost Digit

Problem Description

Given a positive integer N, you should output the most right digit of N^N.

Input

The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
Eac h test case contains a single positive integer N(1<=N<=1,000,000,000).

Output

For each test case, you should output the rightmost digit of N^N.

Sample Input

2  
3  
4  

Sample Output

7  
6

Hint

In the first case, 3 * 3 * 3 = 27, so the rightmost digit is 7.
In the second case, 4 * 4 * 4 * 4 = 256, so the rightmost digit is 6.

Author

Ignatius.L

1003 最右边的数字(翻译)

问题描述

给定正整数N,您应该输出N ^ N的最右边数字。

输入

输入包含几个测试用例。输入的第一行是单个整数T,它是测试用例的数量。T测试案例如下。
每个测试用例包含一个正整数N(1 <= N <= 1,000,000,000)。

产量

对于每个测试用例,您应该输出N ^ N的最右边的数字。

个人理解

也是和1002一样每次进行相乘的时候就直接取10的余数,就不会超时
我个人有个新的想法,因为每次都是最后一个相乘,所以相乘的数字总是在1-9之间,所以只要将1-9之间的每个数的乘积各自定为数组即可
虽然代码量很大,但是思路比较清晰。

代码实现

#include<stdio.h>
int a[2]={1,1};
int b[6]={6,2,4,8,6,2};
int c[6]={1,3,9,7,1,3};
int d[4]={6,4,6,4};
int e[2]={5,5};
int f[2]={6,6};
int g[6]={1,7,9,3,1,7};
int h[6]={6,8,4,2,6,8};
int in[4]={1,9,1,9};
int main() {
	int n;
	if(scanf("%d",&n)==1) {
		for(int i=0;i<n;i++){
			int give,ne,give2;
			scanf("%d",&give);
			give2=give;
			ne=give%10;
			if(ne==1||ne==5||ne==6){
				printf("%d\n",ne);
				continue;
			}
			else if(ne==2){
				give=give%4;
				printf("%d\n",b[give]);continue;
			}
			else if(ne==3){
				give=give%4;
				printf("%d\n",c[give]);continue;
			}
			else if(ne==7){
				give=give%4;
				printf("%d\n",g[give]);continue;
			}
			else if(ne==8){
				give=give%4;
				printf("%d\n",h[give]);continue;
			}
			else if(ne==4){
				give=give%2;
				printf("%d\n",d[give]);continue;
			}
			else if(ne==9){
				give=give%2;
				printf("%d\n",in[give]);continue;
			}
			else if(ne==0&&give!=0){
				printf("0\n");
				continue;
			}
			else{
				printf("1\n");
				continue;
			}
		}
		
	}
	return 0;
}

1004 Climbing Worm

###Problem Description
An inch worm is at the bottom of a well n inches deep. It has enough energy to climb u inches every minute, but then has to rest a minute before climbing again. During the rest, it slips down d inches. The process of climbing and resting then repeats. How long before the worm climbs out of the well? We’ll always count a portion of a minute as a whole minute and if the worm just reaches the top of the well at the end of its climbing, we’ll assume the worm makes it out.

Input

There will be multiple problem instances. Each line will contain 3 positive integers n, u and d. These give the values mentioned in the paragraph above. Furthermore, you may assume d < u and n < 100. A value of n = 0 indicates end of output.

Output

Each input instance should generate a single integer on a line, indicating the number of minutes it takes for the worm to climb out of the well.

Sample Input

10 2 1
20 3 1
0 0 0

Sample Output

17
19

Source

East Central North America 2002

攀爬蠕虫(翻译)

问题描述

一英寸的蠕虫位于n英寸深的底部。它有足够的能量每分钟攀爬一英寸,但是必须休息一分钟然后再攀爬。在休息期间,它滑落了d英寸。攀爬和休息的过程然后重复。蠕虫爬出井前多久了?我们总是将整分钟的一分钟计算在内,如果蠕虫在攀爬结束时刚刚到达井顶,我们就会认为蠕虫会将其击出。

输入

会有多个问题实例。每行包含3个正整数n,u和d。这些给出了上面段落中提到的值。此外,您可以假设d <u且n <100。n = 0的值表示输出结束。

输出

每个输入实例应在一行上生成一个整数,表示蠕虫爬出井所需的分钟数。

个人理解

假如一直到n分钟才爬出来,那么除去最后一分钟,每分钟爬行的高度为u-d

代码实现

#include<stdio.h>
int main() {
	int n,u,d;
	int climb=0,sum=0;
	while(scanf("%d%d%d",&n,&u,&d)==3) {
		if(n==0&&u==0&d==0) {
			break;
		}
		if(n<u) {
			printf("1\n");
			continue;
		} else {
			n=n-u;
			climb=u-d;
			if(n%climb==0) {
				sum=(n/climb)*2+1;
			}
			else{
				sum=(n/climb+1)*2+1;
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}

1005 Balloon Comes!

Problem Description

The contest starts now! How excited it is to see balloons floating around. You, one of the best programmers in HDU, can get a very beautiful balloon if only you have solved the very very very… easy problem.
Give you an operator (+,-,*, / --denoting addition, subtraction, multiplication, division respectively) and two positive integers, your task is to output the result.
Is it very easy?
Come on, guy! PLMM will send you a beautiful Balloon right now!
Good Luck!

Input

Input contains multiple test cases. The first line of the input is a single integer T (0<T<1000) which is the number of test cases. T test cases follow. Each test case contains a char C (+,-,*, /) and two integers A and B(0<A,B<10000).Of course, we all know that A and B are operands and C is an operator.

Output

For each case, print the operation result. The result should be rounded to 2 decimal places If and only if it is not an integer.

Sample Input

4
+ 1 2
- 1 2
* 1 2
/ 1 2

Sample Output

3
-1
2
0.50

Author

lcy

个人理解

这道题没什么难度,注意输出格式即可

代码实现

#include<stdio.h>
int main(){
int n;
if(scanf("%d",&n)==1){
  getchar();
  int i;
  for(i=0;i<n;i++){
  char q;
  int a,b;
  double sum=0.0;
  q=getchar();
  scanf("%d%d",&a,&b);
  if(q=='+'){
     printf("%d\n",a+b);
  }
  else if(q=='-'){
     printf("%d\n",a-b);
  }
  else if(q=='*'){
     printf("%d\n",a*b);
  }
  else if(q=='/'&&a/b-((double)a)/((double)b)==0){
     printf("%d\n",a/b);
  }
  else{
     printf("%.2lf\n",((double)a)/((double)b));
  }
  getchar();
  }
  }
  return 0;
} 

1006 Fibonacci Again

Problem Description

There are another kind of Fibonacci numbers: F(0) = 7, F(1) = 11, F(n) = F(n-1) + F(n-2) (n>=2).

Input

Input consists of a sequence of lines, each containing an integer n. (n < 1,000,000).

Output

Print the word “yes” if 3 divide evenly into F(n).

Print the word “no” if not.

Sample Input

0  
1  
2  
4  
5

Sample Output

no  
no  
yes  
no  
no  
no

个人理解

这道题是类似斐波那契数列,但是有个简单的方法,一直向下寻找,会发现从2开始每隔4个都是yes

代码实现

#include<stdio.h>
int main() {
	int n;
	while(scanf("%d",&n)!=EOF) {
		if((n+2)%4==0) {
			printf("yes\n");
		} else {
			printf("no\n");
		}
	}
	return 0;
}

1007 Number Sequence

Problem Description

A number sequence is defined as follows:
f(1) = 1, f(2) = 1, f(n) = (A * f(n-1) + B * f(n-2)) mod 7.
Given A, B and n, you are to calculate the value of f(n).

Input

The input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line
(1 <= A, B <= 1000, 1 <= n <= 100,000,000). There zeros signal signal the end of input and this test case
is not to be processed.

Output

For each test case, print the value of f(n) on a single line.

Sample Input

1 1 3  
1 2 10  
0 0 0

Sample Output

2  
5

Author

CHEN, Shunbao

Source

ZJCPC2004

个人理解

一开始我想的是前面几个数字可能是独立的,让后到后面就会出现重复,为了防止前面独立的问题,一开始将前面10个用公式算,然后在后面寻找相同,后来发现一开始就会在后面重复,也就是说不需要独立考虑,只要考虑出现两个和第一个第二个相同的时候就出现了相似的单元。

代码实现(因为自己做错并且提交已经结束,借鉴同学的代码)

#include<vector>
#include<iostream>
using namespace std;
​
//定义一个不定长的三维数组用于储存49种情况的循环情况
vector<int> s[7][7];
​
int main() {
int a, b;
long long n;

//在输入前先找出49种情况的循环情况
for(int i = 0; i < 7; i++) {
for(int j = 0; j < 7; j++) {
int sum, kase = 2;
int f1 = 1, f2 = 1;
f1 = (f2 * i + f1 * j) % 7;
f2 = (f1 * i + f2 * j) % 7;
s[i][j].push_back(f1);
s[i][j].push_back(f2);
do {
sum = (s[i][j][kase - 1] * i + s[i][j][kase - 2] * j) % 7;
s[i][j].push_back(sum);
kase = s[i][j].size();
} while(s[i][j][kase - 2] != s[i][j][0] || s[i][j][kase -1] != s[i][j][1]);
s[i][j].pop_back();
s[i][j].pop_back();
}
}

//读入输入直到"0 0 0"为止
while(cin >> a >> b >> n && a != 0 && b != 0 && n != 0) {
if(n <= 2){
cout << 1 << endl;
continue;
}
//对AB分别进行 mod 7 处理
a = a % 7;
b = b % 7;
n = (n - 3) % s[a][b].size();
cout << s[a][b][n] << endl;
}
return 0;
}

}

1008 sort

Problem Description

给你n个整数,请按从大到小的顺序输出其中前m大的数。

Input

每组测试数据有两行,第一行有两个数n,m(0 < n, m < 1000000),第二行包含n个各不相同,且都处于区间[-500000, 500000]的整数。

Sample Input

5 3  
3 -35 92 213 -644

Sample Output

213 92 3  

Author

LL

Source

ACM暑假集训队练习赛(三)

个人理解

想的是用快速排序,但是超时了,后来经过同学帮助,使用堆排序。

代码实现

#include<cstdio>

const int maxn = 1000005;
int a[maxn];
//将m定义为全局变量可表示还需要输出多少数,heapsize用于存储每次输出后剩下数的数量
int heapsize, m;

//用于交换位置
void exchange(const int x, const int y) {
	int temp = a[x];
	a[x] = a[y];
	a[y] = temp;
}

//将数组中i~heapsize间的数据进行从大到小的堆排序
void heap_max(const int i) {
	int left = i * 2;
	int right = left + 1;
	int max2;
	if(left <= heapsize && a[left] > a[i]) max2= left;
	else max2 = i;
	if(right <= heapsize && a[max2] < a[right])max2 = right;
	if(max2 != i) {
		exchange(i, max2);
		heap_max(max2);
	}
}
int main() {
	int n;

	while((scanf("%d %d", &n, &m) != EOF)) {
		for(int i = 1; i <= n; i++) {
			scanf("%d", &a[i]);
		}
		//将heapsize初始化为n
		heapsize = n;

		//将整个数组进行堆排序
		for(int i = n / 2; i >= 1; i--) {
			heap_max(i);
		}

		//先输出最大数并m--
		printf("%d", a[1]);
		m--;

		//重新排序再输出下一个最大数,直到m为0时停止
		while(m) {
			for(int i = n; i >= 2; i--) {
				heapsize--;
				exchange(i, 1);
				heap_max(1);
				printf(" %d", a[1]);
				m--;
				if(m == 0)break;
			}
		}
		printf("\n");
	}
	return 0;
}

1009 吃糖果

Problem Descriptiong

HOHO,终于从Speakless手上赢走了所有的糖果,是Gardon吃糖果时有个特殊的癖好,就是不喜欢将一样
糖果放在一起吃,喜欢先吃一种,下一次吃另一种,这样;可是Gardon不知道是否存在一种吃糖果的顺序使
得他能把所有糖果都吃完?请你写个程序帮忙计算一下。

Input

第一行有一个整数T,接下来T组数据,每组数据占2行,第一行是一个整数N(0 < N < 1000000),第二行是N
个数,表示N种糖果的数目Mi(0 < MI < 1000000)。

Output

对于每组数据,输出一行,包含一个“Yes”或者“No”。

Sample Input

2  
3  
4 1 1  
5  
5 4 3 2 1  

Sample Output

No  
Yes

Author

Gardon

Source

Gardon-DYGG Contest 2

个人理解

只要最大的那一个比剩下的总和大一还要大即可,一开始实现的时候用了排序导致超时了,只要遍历一遍求出总和和最大的就行了,排序是多余的(一开始没想到,哈哈哈)

代码实现

#include<iostream>
using namespace std;
int main() {
	long long t;
	cin >> t;
	while(t--) {
		long long max = 0, sum = 0;
		long long n;
		cin >> n;
		while(n--) {
			long long a;
			cin >> a;
			if(a > max) max = a;
			sum += a;
		}
		if(max > (sum + 1) / 2)cout << "No\n";
		else cout << "Yes\n";
	}
	return 0;
}

1010 Sum Problem

Problem Description

Hey, welcome to HDOJ(Hangzhou Dianzi University Online Judge).
In this problem, your task is to calculate SUM(n) = 1 + 2 + 3 + … + n.

Input

The input will consist of a series of integers n, one integer per line.

Output

For each case, output SUM(n) in one line, followed by a blank line. You may assume the result will be in the range of 32-bit signed integer.

Sample Input

1  
100

Sample Output

1  

5050

个人理解

预处理数据,每个数据都是前一个数据加上自身的值,先预处理一遍就不会溢出了。
注意:最后一排有两个\n。

代码实现

#include<stdio.h>
int main() {
	int a[100000];
	a[1]=1;
	a[2]=3;
	int i,n;
	for(i=3; i<100000; i++) {
		a[i]=a[i-1]+i;
	}
	while(scanf("%d",&n)==1) {
		printf("%d\n\n",a[n]);
	}
	return 0;
}

1011 Elevator

Problem Description

The highest building in our city has only one elevator. A request list is made up with N positive numbers. The numbers denote at which floors the elevator will stop, in specified order. It costs 6 seconds to move the elevator up one floor, and 4 seconds to move down one floor. The elevator will stay for 5 seconds at each stop.
For a given request list, you are to compute the total time spent to fulfill the requests on the list. The elevator is on the 0th floor at the beginning and does not have to return to the ground floor when the requests are fulfilled.

Input

There are multiple test cases. Each case contains a positive integer N, followed by N positive numbers. All the numbers in the input are less than 100. A test case with N = 0 denotes the end of input. This test case is not to be processed.

Output

Print the total time on a single line for each test case.

Sample Input

1 2  
3 2 3 1  
0

Sample Output

17  
41

Author

ZHENG, Jianqiang

个人理解

分布计算向上的楼层总数和下楼的总数,先处理到底要停的时间,比较简单。

代码实现

#include<stdio.h>
int main() {
	int n;
	while(scanf("%d",&n)==1&&n!=0) {
		int a[1000];
		for(int i=1; i<=n; i++) {
			scanf("%d",&a[i]);
		}
		int sum=5*n;
		int up=0,down=0;
		for(int i=1; i<=n; i++) {
			if(i==1) {
				sum=sum+a[i]*6;
			} else {
				if(a[i]>=a[i-1]) {
					up=a[i]-a[i-1];
					sum=sum+up*6;
				} else if(a[i]<a[i-1]) {
					down=a[i-1]-a[i];
					sum=sum+down*4;
				}
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}

1012 七夕节

Problem Description

七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:“你们想知道你们的
另一半是谁吗?那就按照告示上的方法去找吧!”
人们纷纷来到告示前,都想知道谁才是自己的另一半。告示如下:
数字N的因子就是所有比N小又能被N整除的所有正整数,如12的因子有1,2,3,4,6.
你想知道你的另一半吗?

Input

输入数据的第一行是一个数字T(1 <= T <= 500000),它表明测试数据的组数.然后是T组测试数据,每组测试数
据只有一个数字N(1 <= N <= 500000).

Output

对于每组测试数据,请输出一个代表输入数据N的另一半的编号.

Sample Input

3  
2  
10  
20

Sample Output

1  
8  
22

Author

Ignatius.L

Source

杭电ACM省赛集训队选拔赛之热身赛

个人理解

预处理,定义一个数组来存放能除去的数字,通过一遍遍遍历,寻找总和。

代码实现

#include<iostream>
#include<cmath>
using namespace std;
//数组a[n]用于存放n除1外所有因子和,long long以免溢出
const long long maxn = 500001;
long long a[maxn];
int main() {
	long long t;
	//首先进行预处理
	for(long long i = 2; i < sqrt(maxn); i++) {
		a[i * i] += i;
		long long kase = i + 1;
		while(i * kase < maxn) {
			long long sum = i * kase;
			a[sum] += i + kase;
			kase ++;
		}
	}

	//进行多组数据测试
	cin >> t;
	while(t--) {
		long long n;
		cin >> n;
		//因为a[n]不包含因子1,所以输出时要加回去
		cout << a[n] + 1 << endl;
	}
	return 0;
}

个人最后总结

对堆排序还有点陌生,有些时候会干一些多余的事情,考虑问题还算到位,希望自己可以一直坚持下去。加油!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章