第一次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;
}
個人最後總結
對堆排序還有點陌生,有些時候會幹一些多餘的事情,考慮問題還算到位,希望自己可以一直堅持下去。加油!!!