2016年10月9日 星期日

C語言 螺旋矩陣 功課 struct

剛好資料結構出的功課又來寫了一次
struct裡面宣告方法真是機掰,有夠麻煩我還到藍色小舖發問
http://www.blueshop.com.tw/board/FUM20050124191259IGD/BRD20161006215125N33.html

這題是螺旋矩陣
原本以前寫過一次之後再寫,可是覺得寫得太醜了
所以參考一下別人的https://tw.answers.yahoo.com/question/index?qid=20120508000016KK09872
可是中間個那個ax,ay轉換實在是有點亂,所以改了一個易懂的用r[4][2]
以順時針的來就是先走J再走I然後走-J最後走-I
-I走完還要用下一個陣列是否為0來判斷,是否該轉向

#include <stdio.h>
#include <stdlib.h>
#define N 10

struct SpiralMaxtrix
{
int n;
int maxtrix[N][N];
void (*ShowMatrix)(struct SpiralMaxtrix A); /*ShowMatrix是函式指標*/
void (*ShowMatrixR)(struct SpiralMaxtrix A); /*ShowMatrixR是函式指標*/
}A;

void func_ShowMatrix(struct SpiralMaxtrix A)
{
int i=0,j=0,num=1,temp;
int iy=0,jx=0,a=0;
int r[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
while(num<=A.n*A.n){
A.maxtrix[i][j]=num;
iy=i+r[a%4][0];
jx=j+r[a%4][1];
if(iy<0||iy>=A.n||jx<0||jx>=A.n||A.maxtrix[iy][jx]!=0){
a++;
}
i+=r[a%4][0];
j+=r[a%4][1];
num++;
}
for(i=0;i<A.n;i++){
for(j=0;j<A.n;j++){
printf("%-3d",A.maxtrix[i][j]);
}
printf("\n");
}
}

void func_ShowMatrixR(struct SpiralMaxtrix A)
{
int i=0,j=0,num=1,temp;
int iy=0,jx=0,a=0;
int r[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
while(num<=A.n*A.n){
A.maxtrix[i][j]=num;
iy=i+r[a%4][0];
jx=j+r[a%4][1];
if(iy<0||iy>=A.n||jx<0||jx>=A.n||A.maxtrix[iy][jx]!=0){
a++;
}
i+=r[a%4][0];
j+=r[a%4][1];
num++;
}
for(i=0;i<A.n;i++){
for(j=0;j<A.n;j++){
printf("%-3d",A.maxtrix[i][j]);
}
printf("\n");
}
}

int main(int argc, char *argv[])
{
A.ShowMatrix=func_ShowMatrix; /*使用前要先把指標指向真實的函數*/
A.ShowMatrixR=func_ShowMatrixR;
printf("請輸入n:");
scanf("%d",&A.n);
printf("順時針印出:\n");
A.ShowMatrix(A);
printf("逆時針印出:\n");
A.ShowMatrixR(A);
return 0;
}

2016年1月21日 星期四

d649: 數字三角形

內容 :
 小米是個喜歡畫三角形的小朋友
 上課時小米覺得無聊都會在課本的一角畫三角形
 首先畫了
 *
 接著是
 *
 **
 再來
 *
 **
 ***
 就這樣一直畫到下課
 但是這樣太簡單而且太無聊了
 小米想:為何我不向右對齊呢?
 但就在下一節課小米嘗試畫出新三角形時
 小米怎麼樣也沒辦法向右對齊

 就請大家幫小米這個忙吧!
輸入說明 : 
 輸入一數字 N (0 ≤ N ≤ 1000)
 代表小米想畫出高度為 N 的三角形
 當 N 為 0 時結束程式,不需處理這行輸入
輸出說明 : 
 請輸出一個高為 N ,底也為 N 的三角形
 每組輸出請用空行隔開
 空白請用 '_' 代替
 星號請用 '+' 代替
範例輸入 : help
3
5
0
範例輸出:
__+
_++
+++

____+
___++
__+++
_++++
+++++
提示 : 
 ¤ 雙層迴圈練習題
 ¤ 有問題盡量問,這裡不是知識+不會扣點XD (雖然回答也沒有解答贈點)
 ¤ 小挑戰: 你可以用一個字元陣列解決問題嗎?
 ¤ 因應 JAVA 使用者將每測資點時限改為 10 s 並修改測資 (感謝 liouzhou_101)
 ¤ 2010/07/13 修改測資,並重測
標籤:
出處: 


import java.util.Scanner;

public class d649 {

public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();
if(n==0) break;
for(int i=0;i<n;i++){
for(int j=n-1;j>i;j--){
System.out.print("_");
}
for(int k=0;k<=i;k++){
System.out.print("+");
}
System.out.println();
}
}

}

}

d693: 最小公倍數

內容 :
 這題並不是要你算兩個數的最小公倍數,
 因為大家都知道:
      ( from wiki )
 It is too easy!
 想請大家算出 n 個數的最小公倍數! 
輸入說明 : 
 每組測試資料兩行
 第一行有一整數 N ( 2 ≤ N ≤ 10 )
 第二行包含 N 個正整數 ( 每個數 ≤ 100 )
 當 N 為 0 時請結束程式 
輸出說明 : 
 每組測試資料輸出一行
 請輸出 N 個正整數的最小公倍數
 答案保證小於 231-1 
範例輸入 : help
2
3 5
0
範例輸出:
15
提示 : 
 ¤ 感謝 asas 指正範例測資的錯誤
標籤:
出處: 
(管理:example)


import java.util.Scanner;

public class d693 {                                    //兩兩公倍數 相乘

public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();   
if(n==0) break;
            double a,answer=1;
   for(int i=0;i<n;i++){
  a=sc.nextDouble();
  answer=answer*a/GCD(a,answer);   
   }    
   System.out.println((int)answer);    
}
}
static double GCD(double a,double b){
if(a%b==0)
return b;
else
return GCD(b,a%b);
}

}

2016年1月19日 星期二

d827: 買鉛筆

內容 :
鉛筆一支 5 元,一打 50 元。小明需要幫班上每位同學買一枝鉛筆,請問要多少錢?由於小明很注重環保,他絕不會為了省錢而多買任何不需要的東西。也就是說,小明買的鉛筆數量一定等於班上的人數。
輸入說明 : 
輸入只有一行,含有小明班上的人數 n,1 ≤ n ≤ 200。
輸出說明 : 
請輸出一個數字,代表這次採購的金額。
範例輸入 : help
42
範例輸出:
180
提示 : 
標籤:
出處: 


import java.util.Scanner;

public class d827 {

public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();
System.out.println(n/12*50+n%12*5);
}

}

}

d881: 作業苦多

內容 :
學校作業何其多~~老二為此苦惱了許久,現在又有一份數學作業,他想節省時間,所以想找一個程式來解決此問題,你能幫嗎?詳細題目如下:
計算一級數
每項的差形成一個等差數列
每一題給定一等差數列的公差
此等數列有50項,第一項為1
輸出此數列和(1+到50項)
例如輸入為1(此為各項差形成的等差級數的公差) 
答案要輸出1+2+4+7+11+......(到50項) 
若輸入為2
答案要輸出1+2+5+10+17+26+37...... (到五十項)
輸入說明 : 
每次輸入一個測資d,代表公差(d<=100)
輸出說明 : 
輸出級數和(1+到50項)
範例輸入 : help
1
範例輸出:
20875
提示 : 
標籤:
出處: 
CSDC (管理:leepupu)


import java.util.Scanner;

public class d881 {

public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
long total=1;
int n=sc.nextInt(),a=1;
for(int i=2,j=1;j<50;i+=a,j++){
total+=i;
a+=n;
}
System.out.println(total);
}

}

}

d984: 棄保效應

內容 :
台灣的選舉法令禁止各陣營及媒體在投票日前的一個星期內公佈民調結果,其中最重要的一個因素是要避免「棄保效應」。所謂的「棄保效應」是指選民在得知自己所支持的候選人當選無望時,有可能會把票投給其他比較可能當選的人,以免浪費了自己的一票。假設某選舉有三位候選人來競選一個職位,在「棄保效應」發揮到極致的情形下,所有民調第三名的候選人的支持者都會把票投民調第二名的候選人,也就是他們都會「棄三保二」。給你 A, B, C 三個候選人的支持者人數,請判斷誰會當選?
輸入說明 : 
輸入有若干筆測試資料,每筆一行。每行有三個以空白隔開的整數 a, b, c 代表候選人 A, B, C 的支持者人數,0 ≤ a, b, c ≤ 2147483647。你可以假設在「棄保效應」之後,不會有相同票數的情形發生。
輸出說明 : 
請輸出將會當選的人是 A, B 或 C。
範例輸入 : help
3 4 5
1 3 5
範例輸出:
B
C
提示 : 
標籤:
出處: 


import java.util.Scanner;

public class d984 {

public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
long a=sc.nextLong(),b=sc.nextLong(),c=sc.nextLong();
if(a>b && a>c){
if(a>b+c)
System.out.println("A");
else{
System.out.println(b>c?"B":"C");
}
}
else if(b>a && b>c){
if(b>a+c)
System.out.println("B");
else{
System.out.println(a>c?"A":"C");
}
}
else{
if(c>b+a)
System.out.println("C");
else{
System.out.println(a>b?"A":"B");
}
}
}

}

}

2016年1月15日 星期五

d623: 反方陣

內容 :
11
輸入說明 : 
輸入有兩行每行有2個數字代表2階方陣
輸入4個0表示結束
輸出說明 : 
輸出此方陣的反方陣
若此方陣無反方陣則輸出cheat!
範例輸入 : help
1 2
3 4
1 1
1 1
0 0
0 0
範例輸出:
-2.00000 1.00000
1.50000 -0.50000
cheat!
提示 : 
標籤:
出處: 
leopan0922 (管理:leopan0922)


import java.util.NoSuchElementException;
import java.util.Scanner;

public class d623 {

public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
try{
while(sc.hasNext()){
double a=sc.nextDouble(),b=sc.nextDouble(),c=sc.nextDouble(),d=sc.nextDouble();
double temp=1/(a*d-b*c);
if(a==0 && b==0 && c==0 && d==0)
break;
else if(temp==0)
System.out.println("cheat!");
else
System.out.printf("%.5f %.5f\n%.5f %.5f\n",d*temp,-b*temp,-c*temp,a*temp);
}
}catch(NoSuchElementException ex){}

}

}

d587: 參貳壹真好吃

內容 :
參貳壹真是太好吃了!
現在有一連串由1、2、3這三個數字組成的數列,
請你把他們由小到大排好好嗎?
輸入說明 : 
本題有2個測資點,每個50分,每個測資點只有一組測資。
第一行有整數n(1<=n<=1000000)代表接下來的數列有幾個數字
第二行就是這n個包含1、2、3的數字
輸出說明 : 
對於每組測資,請輸出一行由小到大1~3排好的結果。
範例輸入 : help
9
1 1 1 2 2 3 3 3 2
範例輸出:
1 1 1 2 2 2 3 3 3
提示 : 
對於兩個測資點…
第一個測資點(50%)的n是3的倍數,並且1、2、3這三種元素的數量均等
第二個測資點(50%)正常
標籤:
出處: 
jack1 (管理:jack1)


import java.util.Arrays;
import java.util.Scanner;

public class d587 {

public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();
int[] arr=new int[n];
for(int i=0;i<n;i++)
arr[i]=sc.nextInt();
Arrays.sort(arr);
for(int i=0;i<n;i++)
System.out.print(arr[i]+" ");
System.out.println();
}
}

}

d584: 技能點數skill

內容 :
在楓之谷這個線上遊戲裡,
每個人創角色剛開始都是1級的初心者,初心者只有"初心者技能點數",不特別計算。
8級可以轉職成為法師,10級可以轉職成為劍士、弓箭手、盜賊。
轉職後可以拿到技能點數1點,並且在往後每次升級都可以得到3點技能點數。
30級解任務打完討厭的黑色珠子以後,
可以進行第二次轉職,拿到1點技能點數。
70級進行第三次轉職,天阿…要和一轉教官的分身PK,
打贏就可以第三次轉職,拿到1點技能點數。
好不容易練到120級四轉,解了超討厭的轉職任務以後,
第四次轉職可以拿到三點技能點。
最高200級封頂。

現在梅蘭和吳企鵝都玩膩冰雷大魔導士和主教了,
他們正在計畫練分身,請你幫他們算一算某個等級的某職業有多少技能點數呢?
輸入說明 : 
本題有三個測資點,每個測資點有多組測試資料。
每組測試資料一行,有兩個正整數。
第一個正整數表示這個角色的職業,0是初心者、1是劍士、2是法師、3是弓箭手、4是盜賊
第二個正整數表示這個角色的等級lv(1<=lv<=200)
輸出說明 : 
按照說明寫的規則,請輸出這個角色的一生會拿到多少技能點數。
請注意:
1.初心者沒有技能點數,甚至有一種超級初心者完全不轉職可以練到100多等甚至200!
2.我們假設要玩法師的人會乖乖在8等一轉,其它在10等一轉,
並且他們到了30、70、120級也會乖乖自動去轉職。
(也就是假設等級輸入70,那麼請把一轉、二轉、三轉附贈的技能點數都算進去)
範例輸入 : help
0 1
0 9
0 200
1 10
3 11
4 29
4 30
2 30
1 50
3 70
2 120
4 200
範例輸出:
0
0
0
1
4
58
62
68
122
183
342
576
提示 : 
三個測資點的配分分別是30%、35%、35%
第一個測資點和範例測資完全一樣(炸)
第二個測資點還蠻正常的(炸)
第三個測資點…也蠻正常的(炸)
標籤:
出處: 
jack1 (管理:jack1)


import java.util.Scanner;

public class d584 {

public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int job=sc.nextInt();
int LV=sc.nextInt();
int total=0;
if(job==0)
total=0;
else if(job==1 || job==3 || job==4){
 total=(LV-10)*3;
 if(LV>=10) total+=1;
 if(LV>=30) total+=1;
 if(LV>=70) total+=1;
 if(LV>=120) total+=3;  
}
else if(job==2){
 total=(LV-8)*3;
 if(LV>=8) total+=1;
 if(LV>=30) total+=1;
 if(LV>=70) total+=1;
 if(LV>=120) total+=3;
}
System.out.println(total>=0?total:0);
}

}

}

d583: 幼稚的企鵝

內容 :
小企鵝總是天真可愛,但擺脫不了幾分幼稚。
現在企鵝幼稚園的企鵝老師要小企鵝任意排隊。
而小企鵝們卻很堅持要照老師給他們的座號來排隊,
偏偏有的小企鵝就是會忘記自己的座號亂排,
於是可以想見的是一群短鳥喙的小企鵝爭吵互啄的景象了…
輸入說明 : 
本題有2個測資點,每個50分,每個測資點有多組測資。
每組測資的第一行有整數n(1<=n<=100000)代表有幾隻企鵝。
第二行則有n個數字的數列代表每隻企鵝的座號,並且座號必定有1~n不重覆。
輸出說明 : 
請由小到大輸出已經排序的數列。
範例輸入 : help
10
9 5 10 4 3 6 1 2 7 8
30
30 29 28 27 26 25 10 11 12 13 15 14 16 19 18 17 20 24 23 22 21 8 9 7 6 5 3 4 2 1
範例輸出:
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
提示 : 
第一個測資點(50%)和範例測資一模一樣(爆)
第二個測資點(50%)則正常
標籤:
出處: 
jack1 (管理:jack1)


import java.util.Arrays;
import java.util.Scanner;

public class d583 {

public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();
int[] arr=new int[n];
for(int i=0;i<n;i++)
arr[i]=sc.nextInt();
Arrays.sort(arr);
for(int i=0;i<n;i++)
System.out.print(arr[i]+" ");
System.out.println();
}

}

}

d562: 山寨版磁力蜈蚣

內容 :
遊戲洛克人有一個BOSS叫做磁力蜈蚣。
現在山寨版磁力蜈蚣出現了,顯然設計得比本尊弱得很多:
它身上所有的節是由一個個附有數字的磁鐵所組成,
並且會暫時分解自己身上所有的節散落來攻擊玩家。
但是有一天它發現它身上的節居然隨著絕招的使用越來越少!
每次山寨版磁力蜈蚣將自己分解時,會讓所有磁鐵的排列順序倒轉。
例如原本是:1 2 3 4 5,那麼倒轉後便成了5 4 3 2 1
但是現在每次分解前便會先遺失第一節磁鐵,
也就是原本:1 2 3 4 5,會遺失1,
剩下的磁鐵倒轉後是5 4 3 2
下次分解會遺失5,剩下的倒轉成了2 3 4
,再遺失2,成了4 3,最後剩下3便無法分解。
請利用程式來模擬這個過程。
輸入說明 : 
共計三個測資點。
每組測資有兩行
第一行有整數n(0<n<100)代表有幾個數,
第二行有n個數A1...An(0<An<100)表示每個磁鐵上的數字
輸出說明 : 
第一行請輸出最一開始的狀態
第二行開始,輸出「刪去第一項後,全部倒轉的結果」
直到數字只剩下一個為止
範例輸入 : help
5
99 77 66 44 11
7
1 98 95 52 56 34 43
範例輸出:
99 77 66 44 11
11 44 66 77
77 66 44
44 66
66

1 98 95 52 56 34 43
43 34 56 52 95 98
98 95 52 56 34
34 56 52 95
95 52 56
56 52
52
提示 : 
這只是山寨板的蜈蚣,如果這題對你輕而易舉,請試試morris1028出的強化蜈蚣:
http://zerojudge.tw/ShowProblem?problemid=d569
標籤:
出處: 
jack1 (管理:jack1)

import java.util.Scanner;

public class d562 {

public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();
int[] arr=new int[n];
for(int i=0;i<n;i++)
arr[i]=sc.nextInt();
int start=0,end=n,flag=0;
String str;                                     //改用字串一次println出來居然比較快...
for(int i=flag;i<=n/2;i++){
str="";
while(flag<end){
//System.out.print(arr[flag]+" ");
str+=arr[flag]+" ";
flag++;
}
System.out.println(str);
end--; flag--;
str="";
while(flag>start){
//System.out.print(arr[flag]+" ");
str+=arr[flag]+" ";
flag--;
}
start++; flag++;
System.out.println(str);
}
}

}

}