Codeforces Round #392 (Div. 2) - B
题目链接:http://codeforces.com/contest/758/problem/B
题意:给定n个点灯的情况,灯只有四种颜色RBGY,然后如果某个灯坏了则用'!'表示,现在要求将坏的灯(即'!'的位置)用其他新的灯来替换(新灯只有前面描述的四种颜色),并且要满足最后的灯序列每连续四个位置的灯的颜色都不一样(即分别是给定的四种颜色,顺序任意)。问最后要用每种颜色的灯的数目。题目保证输入一定合法,即一定存在一个符合条件的序列
思路:因为每连续四个位置要满足颜色不一样的要求,所以我们可以单独枚举前四个位置坏的灯的颜色,然后后面的位置就可以递推来求得。用二进制的1111标准四种颜色灯出现的次数,1表示出现了,0表示没有出现。然后如果四个位置的值不为15(二进制表示1111)表示这个序列不符合题目要求,继续枚举下一种情况。
import java.io.PrintWriter; import java.util.*; public class Main { public static boolean flag; public static String color = "RBYG"; public static StringBuffer s; public static int ans[] = new int[color.length()]; public static void dfs(int idx,StringBuffer str) { if (flag == true) { return; } if (idx >= 4) { flag = check(new StringBuffer(str)); return; } if (str.charAt(idx) == '!') { for (int i = 0; i < 4 && flag == false; i++) { str.setCharAt(idx, color.charAt(i)); dfs(idx + 1,new StringBuffer(str)); } } else { dfs(idx + 1,new StringBuffer(str)); } } public static boolean check(StringBuffer str) { int val = 0; for (int i = 0; i < str.length(); i++) { if (str.charAt(i) == '!') { for (int j = 0; j < 4; j++) { if ((val & (1 << j)) == 0) { str.setCharAt(i, color.charAt(j)); val |= (1 << j); } } } else { val |= (1 << color.indexOf(str.charAt(i))); } if (i >= 3 && val != 15) { return false; } if (i >= 3) { val ^= (1 << color.indexOf(str.charAt(i - 3))); } } s=str; return true; } public static void main(String[] args) { Scanner cin = new Scanner(System.in); PrintWriter out = new PrintWriter(System.out); String str = cin.next(); s = new StringBuffer(str); flag = false; dfs(0,new StringBuffer(str)); Arrays.fill(ans, 0); //out.println(s); for (int i = 0; i < str.length(); i++) { if (str.charAt(i) == '!') { ans[color.indexOf(s.charAt(i))]++; } } for (int i = 0; i < 4; i++) { out.printf("%d", ans[i]); out.printf("%c", i == 3 ? '\n' : ' '); } cin.close(); out.flush(); } }