AOJ2190 Angel Stairs
問題リンク Angel Stairs
- 解法
逆向きに考えます。
まず、N+1段目に降り立つには、直前にNかN-1段目にいることになります。
N段目にいたとします。このN段目にいるには、Tnを踏んでSmの音を出さないといけないです。そして、TnをSmの音で出すためにどう踏むかは高々1通りしかありません。逆向きに考えると、直前にどこにいたかは(最初をのぞいて)一意に決まるので、O(M)でチェックできます。
これを、N段目からさかのぼる、N-1段目からさかのぼる、の2通り試してどちらかで、Sの曲を弾いて0段目に戻れたならば答えはYesです。
- ソース
import java.util.Scanner; //Angel Stairs public class AOJ2190 { String[] f = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}; int trans(String s){ for(int k=0;k<12;k++)if(f[k].equals(s))return k; return 0; } void run(){ Scanner sc = new Scanner(System.in); int T = sc.nextInt(); while(T--!=0){ int n = sc.nextInt(), m = sc.nextInt(); int[] t = new int[n+2]; t[0] = t[n+1] = -1; for(int i=1;i<=n;i++)t[i]=trans(sc.next()); int[] s = new int[m]; for(int i=0;i<m;i++)s[i]=trans(sc.next()); int p = n; boolean con = true; for(int k=m-1;k>=0&&con;k--){ con = false; if(p==0||p==n+1)break; int np = p-2; if(0<=np&&s[k]==(t[p]+1)%12){ con = true; p = np; continue; } np = p-1; if(0<=np&&s[k]==t[p]){ con = true; p = np; continue; } np = p+1; if(np<=n&&s[k]==(t[p]+11)%12){ con = true; p = np; continue; } } if(con&&p==0){ System.out.println("Yes"); continue; } p = n-1; if(0<=p){ con = true; for(int k=m-1;k>=0&&con;k--){ con = false; if(p==0||p==n+1)break; int np = p-2; if(0<=np&&s[k]==(t[p]+1)%12){ con = true; p = np; continue; } np = p-1; if(0<=np&&s[k]==t[p]){ con = true; p = np; continue; } np = p+1; if(np<=n&&s[k]==(t[p]+11)%12){ con = true; p = np; continue; } } if(con&&p==0){ System.out.println("Yes"); continue; } } System.out.println("No"); } } public static void main(String[] args) { new AOJ2190().run(); } }