最近阿宅迷上了一款二次元游戲叫<<解救公主>>。
其中有一關的規則是這樣的
公主被困在夢境里,夢境里的空間無限大,公主靠自己是走不出來的。
系統會隨機很多條行動指令,玩家必須幫公主選出正確的指令,公主按照玩家選擇的指令,重復執行若干次后就能走出困境。
指令有三個字符組成 S,R,L
S: 前進一步
R: 向右轉
L: 向左轉
如果公主重復執行錯誤的指令,她就會一直在繞圈子,走不出夢境。
所謂“繞圈子”是指:無論公主重復執行多少次指令,她始終都在一個以出發點為圓心,以R為半徑的圓里,永遠走不出這個圓,更走不出夢境。
阿宅已經卡在這一關很久了。他很痛苦不能早日拯救公主脫離苦海,于是向聰明的你求助,讓你寫段代碼判斷哪些指令是正確的,哪些指令是錯誤的。
輸入:
第一行 一個整數n
之后共有n行,每行為一個指令串
輸入約束:
n位于區間[1,50]
從第二行開始,每行指令串長度為1-50,且僅包含字母 S,L,R
輸出:
僅有一個單詞。
指令串錯誤 列印 no
指令串正確 列印 yes
舉例1:
輸入
1
SLSR
輸出
yes
解釋:假設公主初始狀態向北,公主的行動序列依次為前進,左轉,前進,右轉,此時公主仍然向北,但位置已經移動了。只要時間足夠長,公主會一直向這個方向前進,所以公主沒有在繞圈子。她能走出夢境,指令是正確的
舉例2:
輸入
2
SSSS
R
輸出
no
解釋: 公主一直在沿著一個邊長為4步的小正方形繞圈子,指令是錯誤的
uj5u.com熱心網友回復:
我的初步想法是模擬,根據他輸入的指令,來模擬走法,最后判斷下 全部走完之后和初始點的位置差距如果和初始點一樣,就是no,否則就是yes
uj5u.com熱心網友回復:
數一下所有的指令序列,里面的L的個數必須等于R的個數,否則,L和R之間存在S,就會繞圈。這是數學題吧? 編程不是關鍵。
uj5u.com熱心網友回復:
我覺得只要指令能保證一下兩個條件就可以(其實就是結合1L和2L的條件)一是,指令執行完后方向不變(即L和R抵消)//光方向不變不行,還要不能停留在原來的位置,比如LLSSRRSS,方向不變,實在停留在原點
二是,指令執行完后位置改變(即不停留在原地)//光位置有改變不行,還要方向不變,LZ的例子的SSSSR就是這個問題,不管轉L還是轉R都是90度轉,第4次就會360度轉回到原點,如果是LL或RR180度轉,那第二次就會回到原點
所以,綜上,我覺得只要同時滿足條件1和2,就不會饒圈子(也就是不管怎么重復,都是勇往直前
)代碼sample
import java.util.Random;
import java.util.Scanner;
public class Sample {
public static void main(String[] args) {
boolean test = true; //用戶手動輸入改成false即可
String[] cmd;
if (!test) {
System.out.println("輸入");
cmd = getUserInput();
System.out.printf("輸出\n%s\n", checkCmd(cmd));
} else { //自動測驗
for (int i=0; i<5; i++) {
cmd = getRandomCmd(i);
System.out.printf("測驗%d\n輸入\n%d\n", i+1, cmd.length);
for (String s : cmd) {
System.out.println(s);
}
System.out.printf("輸出\n%s\n\n", checkCmd(cmd));
}
}
}
public static String[] getUserInput() {
Scanner sc = new Scanner(System.in);
int n = 0;
while (true) {
try {
//System.out.println("請輸入1-50之間的數字:");
n = Integer.valueOf(sc.nextLine());
if (n>0&&n<51) break;
} catch (Exception e) {
n = 1; //default
break;
}
//System.out.println("輸入錯誤,請重輸。");
}
String []cmd = new String[n];
for (int i=0; i<n; i++) {
while(true) {
try {
//System.out.printf("請輸入第%d行指令(指令必須有[LRS]中字母構成其總長度不超過50):");
cmd[i] = sc.nextLine();
if (cmd[i].matches("[LRS]{1,50}")) break;
} catch (Exception e) {
cmd[i] = "S"; //default
break;
}
//System.out.println("輸入錯誤,請重輸。");
}
}
return cmd;
}
public static String checkCmd(String[] cmd) {
int angle=0, x0=0, y0=0, x=x0, y=y0; //方向(角度),距離
for (String s : cmd) {
for (char c : s.toCharArray()) {
if (c=='L') {
angle -= 90; //以左轉為-90度
} else if (c=='R') {
angle += 90; //右轉為+90度
} else if (c=='S') { //以北為0度
int m = angle%360;
if (m==0) y++; //往北走
else if (m==-90 || m==270) x--; //往西走
else if (m==180 || m== -180) y--; //往南走
else if (m==-270 || m==90) x++; //往東走
}
}
}
if (angle%360==0 && (x!=x0 || y!=y0)) { //如果方向不變位置改變
return "yes";
} else {
return "no";
}
}
}
uj5u.com熱心網友回復:
忘了發測驗資料的代碼了說明一下,方向不變還是看L和R抵消,而是看轉的角度%360是否和原來一樣。因為LLLLS沒有R抵消也是方向不變(轉了360度),所以它也是yes
完整代碼
import java.util.Random;
import java.util.Scanner;
public class Sample {
public static void main(String[] args) {
boolean test = true; //用戶手動輸入資料改成false即可
String[] cmd;
if (!test) {
System.out.println("輸入");
cmd = getUserInput();
System.out.printf("輸出\n%s\n", checkCmd(cmd));
} else { //自動測驗
for (int i=0; i<5; i++) {
cmd = getRandomCmd(i);
System.out.printf("測驗%d\n輸入\n%d\n", i+1, cmd.length);
for (String s : cmd) {
System.out.println(s);
}
System.out.printf("輸出\n%s\n\n", checkCmd(cmd));
}
}
}
public static String[] getUserInput() {
Scanner sc = new Scanner(System.in);
int n = 0;
while (true) {
try {
//System.out.println("請輸入1-50之間的數字:");
n = Integer.valueOf(sc.nextLine());
if (n>0&&n<51) break;
} catch (Exception e) {
n = 1; //default
break;
}
//System.out.println("輸入錯誤,請重輸。");
}
String []cmd = new String[n];
for (int i=0; i<n; i++) {
while(true) {
try {
//System.out.printf("請輸入第%d行指令(指令必須有[LRS]中字母構成其總長度不超過50):");
cmd[i] = sc.nextLine();
if (cmd[i].matches("[LRS]{1,50}")) break;
} catch (Exception e) {
cmd[i] = "S"; //default
break;
}
//System.out.println("輸入錯誤,請重輸。");
}
}
return cmd;
}
public static String checkCmd(String[] cmd) {
int angle=0, x0=0, y0=0, x=x0, y=y0; //方向(角度),距離
for (String s : cmd) {
for (char c : s.toCharArray()) {
if (c=='L') {
angle -= 90; //以左轉為-90度
} else if (c=='R') {
angle += 90; //右轉為+90度
} else if (c=='S') { //以北為0度
int m = angle%360;
if (m==0) y++; //往北走
else if (m==-90 || m==270) x--; //往西走
else if (m==180 || m== -180) y--; //往南走
else if (m==-270 || m==90) x++; //往東走
}
}
}
if (angle%360==0 && (x!=x0 || y!=y0)) { //如果方向不變位置改變
return "yes";
} else {
return "no";
}
}
public static String[] getRandomCmd(int uc) { //測驗資料
if (uc==0) return new String[] {"LLLLS"};
else if (uc==1) return new String[] {"SSSS", "R"};
char[] chs = {'L', 'R', 'S'};
Random rad = new Random();
if (uc>49) uc=49;
int n = rad.nextInt(uc+1) + 1;
String[] cmd = new String[n];
for (int i=0; i<n; i++) {
int len = rad.nextInt(50) + 1;
StringBuilder buf = new StringBuilder();
for (int j=0; j<len; j++) {
buf.append(chs[rad.nextInt(3)]);
}
cmd[i] = buf.toString();
}
return cmd;
}
}
uj5u.com熱心網友回復:
暈,方向不變不是看L和R抵消
錯別字
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/50890.html
標籤:Java EE
