PTAラダートーナメントの積み重ね順序
複数の書き込み方法、コンテナー、配列
最大容量がMのスタックがある場合、1、2、3、…、Nの順序でN個の番号をスタックに配置し、それらを任意の順序でポップできるようにします。取得できない番号のシーケンスはどれですか。たとえば、M = 5およびN = 7の場合、{1、2、3、4、5、6、7}を取得できますが、{3、2、1、7、5、6を取得することはできません。 4}。
入力フォーマット:
最初の行を入力して、1000を超えない3つの正の整数を指定します:M(最大スタック容量)、N(スタックにプッシュされた要素の数)、およびK(チェックされるスタックされていないシーケンスの数)。最後のK行では、各行にN個の数字のポップシーケンスが示されています。同じ行のすべての数字はスペースで区切られます。
出力フォーマット:
ポップアップシーケンスの各行について、それが実際に正当なシーケンスである可能性がある場合は、1つの行にYESを出力し、そうでない場合はNOを出力します。
入力サンプル:
5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2
サンプル出力:
YES
NO
NO
YES
NO
はしごゲームシミュレーションゲームは、残念ながら当時は非常に複雑で、何度も変更した後も2、3例ありましたが、書いた人の数を見るとひどいものでした。
次の段落はナンセンスです。
私の最初のアイデアは非常に一般的で、実装するのは非常に面倒でした。判断することがたくさんあります。つまり、スタックから数えるときは、最初にスタックが現在いっぱいかどうかを判断する必要があります。また、どれを判断する必要があります。要素はすでにスタックから外れています。スタックにいない場合は、スタック内の要素がスタックからポップされた要素よりも大きくなることはできないことも確認する必要があります。つまり、ループはループを設定し、マーク、それがどれほど面倒か、どれだけ面倒かを追加します。
——————————————————————————
******実際、一般的な言葉で考えるとき、それはしばしば非常に面倒であり、新しい新しい考え方を必要とします。
******質問では、スタックの順序が妥当かどうかを判断する必要があります。質問
の意味に従い、スタック上の要素が小さいものから大きいものへと1つの要素をスタックに配置します。スタック上の要素の場合、ファミリは要素Stack、top–;を削除してから、要素を配置し続けます。すべての要素を配置できる場合は、スタックの順序が適切であることを意味します。
プロセスで発生した問題:
1.スタックの判断方法がいっぱいです。
------- topによると、topはスタックの最上位を表すだけでなく、スタック内の要素も表します。要素をスタックに一度プッシュして++ topを実行しますが、同時に、ポップする必要のある要素がスタック内の要素と一致している場合は、top–も実行してスタックをポップします。したがって、top> mの場合、スタックがオーバーフローしたことを示している可能性があります。
2.スタック内の要素がポップされた要素よりも大きいと判断する方法
スタックは小さいものから大きいものまで選択されるため、この問題を考慮する必要はありません。
3.どの要素がスタックからポップされたかを知る方法
実際には気にする必要はありません。トップはすでにスタック内の要素の数を示しているので、どの要素がポップされたかに注意を払う必要はありません。飛び出し。
したがって
、このアイデアを使用すると、操作がはるかに簡単になります
———————-----------———————————————–
方法1:配列を使用して書き込みます
#include<stdio.h>
#include<string.h>
int a[1100],sta[1100];
int main()
{
int m,n,k;
scanf("%d %d %d",&m,&n,&k);
while(k--)
{
int i,j;
sta[0]=-1;//给sta[0]赋一个永远不可能与出栈元素相等的值
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
int w=1,top=0;
sta[++top]=w;//首先让1入栈
i=1;
while(i<=n)//按照出栈顺序让栈内元素出栈
{
while(a[i]==sta[top])//当前栈顶满足出栈要求,降低top
{
top--;//栈顶出栈
i++;//新的栈顶与下一个将要出栈的元素进行对比
//下面的可以不需要,因为sta[0]==-1
//if(top==0)//栈内无元素了,不可能再出栈了
// break;
}
//栈顶元素小于要出栈的元素,说明此刻要出栈的元素还没有进栈呢
//出栈元素要进栈,那比它小的肯定得比它先进栈
if(a[i]!=sta[top])
{
sta[++top]=++w;//注意++w,用意在于进过栈的元素不可能二次进栈,无论是未出栈的,还是出过栈的,进栈机会只有一次
}
if(top>m||w>n)//栈溢出,或者所有的元素都进栈了
break;
}
//出栈顺序合法,栈顶最终指向1
if(i==n+1)//当然只有当所有出栈顺序和合法的时候才YES,这一条件是必须的
printf("YES\n");//所有出栈顺序合法,没有问题
else
printf("NO\n");
}
}
方法2:コンテナを使用して書き込みます
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
using namespace std;
int a[1010];
stack<int>st;//容器栈,先进后出
int main()
{
int m,n,k;
scanf("%d %d %d",&m,&n,&k);
while(k--)
{
int i,w=1;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
while(!st.empty())
st.pop();
st.push(w);//从1开始进栈
i=1;
while(i<=n)//一个一个判定合法顺序
{
while(a[i]==st.top())
{
st.pop();//删除栈顶元素
i++;
if(st.empty()!=0)//栈为空了就可以跳出循环了
break;
}
if(st.empty()!=0||a[i]!=st.top())
{
st.push(++w);
}
if(st.size()>m||w>n)
break;
}
if(i==n+1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}