您的位置:首页 > 其它

srm 300 div2 1000(贪心进阶)

2015-03-29 01:06 429 查看
题意:

有一个环,上面2n个位置,其中n个互不相同的小写字母。

小写代表车,大写代表车位。

一次操作是指把某辆车直接移动到车位上。

如 BACacb,一个合法的移动顺序是,a, c, b

求出字典序最小的移动顺序,如果无解输出NONE。

思路:

贪心策略:每次取字典序最小的可以移动的车移动, 如果不存在。则无解。

如果最后有解,因为每次取最小,所以自然是最小字典序。

但是,怎么在无解的情况下,其他的取法也不可能有解呢?

假设…c….C….现在最小的可以移动的车是c

如果存在一个合法顺序,把c放到以后来移动。那么c…C之间的一段在c移动之前一定都是空的, 也就意味着c的移动顺序可以被提前。

string notok = "NONE";

class CircleOrder
{
public:
string firstOrder(string circle)
{
int len = circle.length();
vector<int> used(26), p(26);
fill(used.begin(), used.end(), 1);
rep(i, 0, len-1) if (islower(circle[i])) used[circle[i] - 'a'] = 0;
rep(i, 0, len-1) if (islower(circle[i])) p[circle[i] - 'a'] = i;
string ans = "";
rep(i, 1, len/2) {
int ok = 0, choice;
rep(j, 0, 25) if (used[j] == 0) {
int can = 0;
int pos = p[j];
while ( (islower(circle[pos]) && used[circle[pos] - 'a'] || isupper(circle[pos]) && !used[circle[pos] - 'A'] || circle[pos] - 'a' == j)
&& circle[pos] != j+'a'-('a'-'A')) { pos += 1;if (pos == len) pos = 0;}
if (circle[pos] == j+'a'-('a'-'A')) {ok = 1;choice = j;break;}
pos = p[j];
while ( (islower(circle[pos]) && used[circle[pos] - 'a'] || isupper(circle[pos]) && !used[circle[pos] - 'A'] || circle[pos] - 'a' == j)
&& circle[pos] != j+'a'-('a'-'A')) { pos -= 1;if (pos < 0) pos = len-1;}
if (circle[pos] == j+'a'-('a'-'A')) {ok = 1;choice = j;break;}
}
if (ok) {
ans += choice + 'a';
used[choice] = 1;
}
else
return notok;
}
return ans;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: