玉
図のように二股に分かれている容器があります。1 から 10 までの番号が付けられた10 個の玉を容器の開口部 A から落とし、左の筒 B か右の筒 C に玉を入れます。板 D は支点 E を中心に左右に回転できるので、板 D を動かすことで筒 B と筒 C のどちらに入れるか決めることができます。
開口部 A から落とす玉の並びを与えます。それらを順番に筒 B 又は筒 Cに入れていきます。このとき、筒 B と筒 C のおのおのが両方とも番号の小さい玉の上に大きい玉を並べられる場合は YES、並べられない場合は NO と出力するプログラムを作成してください。ただし、容器の中で玉の順序を入れ替えることはできないものとします。また、続けて同じ筒に入れることができるものとし、筒 B, C ともに 10 個の玉がすべて入るだけの余裕があるものとします。
Input
複数のデータセットが与えられます。1行目にデータセット数 N が与えられます。つづいて、N 行のデータセットが与えられます。各データセットに 10 個の番号が左から順番に空白区切りで与えられます。
Output
各データセットに対して、YES または NO を1行に出力して下さい。
Sample Input
2 3 1 4 2 5 6 7 8 9 10 10 9 8 7 6 5 4 3 2 1
Output for the Sample Input
YES NO
给十个数, 问能不能至多按顺序变成两个递增序列。
一打开发现是满篇的日文, 又被归类在搜索里面了, 不禁默默打开了百度翻译。。。
但是其实就是一个很简单的贪心(先可着一个放,两个都放了之后可着大的序列放)而且竟然没有人这么写(一定是我的方法菜到不屑于敲那么多。。。嗯), ac之后看了大牛们写的方法。 那都是些啥???(开始记笔记)
然后又从笔记里写了一种DFS的, 看着贼高端也节省了代码量。
暴力贪心
#include
using namespace std;
int main() {
int t;
scanf("%d", &t);
while (t--) {
int a = -1, b = -1, temp;
bool flag = 0;
for(int i = 0; i < 10; ++i) {
scanf("%d", &temp);
if (a == -1 && b == -1) {
a = temp;
continue;
}
if (a != -1 && b == -1) {
if (temp > a) a = temp;
else b = temp;
continue;
}
if (temp <= a && temp <= b)
flag = 1;
else if (temp > a && temp < b)
a = temp;
else if (temp > b && temp < a)
b = temp;
else if (temp > b && temp > a) {
if (b > a) b = temp;
else a = temp;
}
}
if (flag) printf("NO\n");
else printf("YES\n");
}
return 0;
}
DFS
#include
using namespace std;
int arr[15];
bool DFS(int l, int r, int i) {
if (i == 10) return true;
return ( ((!~l||arr[i]>arr[l]) && DFS(i, r, i+1)) || ((!~r||arr[i]>arr[r]) && DFS(l, i, i+1)));
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
for (int i = 0; i < 10; ++i)
scanf("%d", &arr[i]);
if (DFS(-1, -1, 0)) printf("YES\n");
else printf("NO\n");
}
return 0;
}