PTAは、4週ノート

おいしいチョコレート

特別なスーパーマーケットはちょうど貪欲Lucky_dogソーように、チョコレートを販売しています。
行の右、Nの合計、M種に左からチョコレート。
スーパーマーケットは、非常に奇妙なルールは、あなたが間(aとbを含む)、B番目のチョコレートに目を購入したいすべてのチョコレートを代表して、チョコレートの購入に二つの数aとbを提供しなければならないということである持っています。
すべてのチョコレートが$ 1販売されていますと仮定すると。Lucky_dogはチョコレートのすべての種類を食べたいが、お金を節約したいです。Lucky_dogの友人として、彼は彼がチョコレートを買うときaとbを選択する方法を決定するのを助けるためにお願いします。
入力フォーマット:
最初の行は、2つの正の整数N及びM(M <= N、N含有する 、<= 10 ^ 6、M <= 2000) 総数とチョコレートの種類の数を表します。
二行目は、N個の整数を含む、チョコレート属する代表の種類に対応する1とMの間の整数です。
出力フォーマット:
スペースで区切られた2つの整数aとb(<= B)を含むのみ出力ライン、および最も安価なタイプは、すべてのチョコレート後のセクションを含む表します。
より多くの適格購入間隔は、その最小の出力が存在する場合、データは、解決策を保証します。

输入样例:
12 5
2 5 3 1 3 2 4 1 1 5 4 3
输出样例:
在这里给出相应的输出。例如:
2 7

私自身のアルゴリズムでは大きな神の助けがない場合、タイムアウトがされているので、それは渡しません、この質問はから来ている展覧会を訪れたロス・バレーP1638問題解決がより豊富ですが、私は自分の考えをまとめるしたいと思います。

アイデア:右最初の右端から最初の数字、1からMまでのすべての番号を含むまでとし、1からMまでの各番号の出現回数を算出し、左の点をチェックし、二回二回の出現数であれば以上、右、及びデジタル数から1を引いた左点。これは、初期間隔(後の説明を参照)ビットよりも小さい範囲を取ることができる最初の範囲は、チェックを決定する手順は、次の再反復した後、数でそのコードを完成を決定します。(比較巧妙な技術は、ギャングスターを学ぶための方法です)

#include<stdio.h>
int a[1000000],b[2005];//全局变量初始值为0 
int main()
{
    long int N;
    int M,r=0,i,R=0,L=1,R1,L1;
    scanf("%ld%d",&N,&M);
    for(i=0;i<N;i++)
        {
            scanf("%d",&a[i]);
         } 
    i=0;
    while(r!=M){
        if(b[a[i]]==0)r++;
        b[a[i]]++;
        i++;
        R++;
    }//确定一个初始右端点
    while(b[a[L-1]]>1){
        b[a[L-1]]--;
        L++;
    } //右移左端点,缩小区间 
    R1=R;
    L1=L;//确定初始区间
    while(i<N){
        b[a[i]]++;
        R++;
        i++;
        while(b[a[L-1]]>1){
            b[a[L-1]]--;
            L++; 
        }
        if(R-L<R1-L1){
            R1=R;
            L1=L;
        }
    }//遍历检查是否有更小的区间
    printf("%d %d",L1,R1);
    return 0;
}

特殊翻訳

暁明の作品は、英語の文字の特殊な翻訳の文字列を実行されます。同じ連続と小文字が大文字に置き換えられるために、表示されたときに、連続した大文字の背中の文字の数は小文字が続きます;同時に、左右の連続ストリング交換小文字の文字列の位置は、この動作は同じ小文字文字までない連続するまで繰り返されます。今暁明は、彼がこの特定の翻訳を完成助けるためにあなたを招待したいと思います。
入力フォーマット:
小文字からなる文字列入力文字列。(文字列長が250より大きくない)
出力フォーマット:
翻訳された文字列を出力します。

输入样例1:
dilhhhhope
输出样例1:
在这里给出相应的输出。例如:
opeH4dil
输入样例2:
lodnkmgggggggoplerre
输出样例2:
在这里给出相应的输出。例如:
eG7lodnkmR2ople  

ただ、我々が対処するのは難しいそれらの同じ配列をしたい場合は、等しいか、それはまた、私にSilu孟を解決するための層を与えた文字列内のいくつかの連続した文字列を表示されていない主な文字列で、混乱を考え始めます霧(つまり、婉曲表現の非常に混乱して考えです)思考の私の電車に説明するために、今、明確な問題解決の手順で、他の学生の問題解決のアイデアの学習、そして後。

アイデア:まず、私は思うタイトルがそれが連続した文字に遭遇した場合、連続した文字列を交換して、文字列を変更し、トラバースに進み最初の左右への最初の一続きの文字列を検索、複雑ではありません文字列全体が小の連続列がなくなるまでステップ、上記文字列が繰り返されます。一般的な考えはこれです、また、全体のフレームワークを持っていました。治療のための文字列のやり取りが続き、私は文字の3つの新しい配列、文字、右の文字を変更、左を格納するために使用される各文字を開きました。そして、そこに非常に重要なステップは、ある元の文字列をクリアすることで、その後、右の文字に、文字を変更、オーダーの左側の文字を新しい文字列に割り当てられます。

全体的な感触はコードに非常に重要であり、私はすべてのコードを添付します、と私は忘れて簡単に解釈するために、コード内でマークされ、状況を無視するいくつかの簡単なを持っています。

#include<stdio.h>
#include<string.h>
char s1[250],s2[5],s3[250],s[250];
int main()
{
    int n,i,t=1,a,b,x,j;
    scanf("%s",s);
    n=strlen(s);
    for(i=0;i<n-1;i++)
        {
            if(s[i]==s[i+1]&&s[i]<123&&s[i]>96){//连续的字符串得是小写字母,必须附上这一判断,不然当字符个数为22或33时会出现差错
                while(s[i]==s[i+1]){
                    t++;
                    i++;
                }
                a=i-t+1;
                b=i+1;
                for(x=b,j=0;s[x]!='\0';x++)
                    {
                        s3[j]=s[x];
                        j++;
                    }
                strncpy(s1,s,a);
                
                s2[0]=s[i]-32;
                i=1;
                memset(s,'\0',n);
                if(t<10){
                    s2[i]=t+48;
                    n=a+2+j;
                    }
                else if(t>9){
                    s2[i]=t/10+48;
                    i++;
                    s2[i]=t%10+48;
                    n=a+3+j;
                    }//对于连续的字符个数大于9的处理
            
            for(i=0;i<j;i++)
                {
                    s[i]=s3[i];
                }
            if(t<10){
                s[i]=s2[0];
                i++;
                s[i]=s2[1];
                i++;
            }
            else if(t>9){
                s[i]=s2[0];
                i++;
                s[i]=s2[1];
                i++;
                s[i]=s2[2];
                i++;
            }//这一部分写得比较繁琐了,优点就是方便理解,嘿嘿嘿
            for(x=0;x<a;x++)
                {
                    s[i]=s1[x];
                    i++;
                }
            i=-1;//进入新的for循环后会i++,之后就会变为0   
            t=1;
            }
            
        }
    printf("%s",s);
    return 0;
}

次回(続き)

:あなたは今、あなたがコイン増加のルールを開発した夢の中で、夢を持っていた、多くの場合、キーのトリプル、そうでないコインとして、6つの数字の嗶哩嗶哩ある
硬貨の合計数を上陸の最初の日の後コイン112の次の日の合計数、コイン112 123の合計数を着陸の三日目......と分からない太陽と月のように、夢を着陸した後、あなたは即座に11212312341234512345612345671234567812345678912345678910123456789101112345678910の無限の数を持っている......コイン。
年間保守ステーションB受注百のドリフト奇妙なスタンド、そしてあなたが正しくあなたとあなたに提示されたものを、このXビットにいくつかを答えることができるならば、この無限の数のxビットとして、乱数xを選ぶことにしましたコインの同じ量の数。
百人ののドリフト非難の合計は、T回を迎えます。
あなたはプログラミングのシミュレーションは、それを行く、変更原動機付自転車を与えるかを決めます。
入力フォーマットは:
最初の行は、正の整数t(1≤t≤10)を含有する100倍のTドリフト奇妙なピックを表します。次T線、各正の整数X(≤x≤2 ^ 31-1 1 )、 i番目の百個のドリフト奇妙ピック最初のXビットを表します。
出力形式:
出力コモンT行、Xビットに対する出力の数に対応する行。

输入样例1:
2
3
8
输出样例1:
2
2
输入样例2:
6
222
66666
99999999
66656565
22222
2
输出样例2:
6
4
9
4
1
1

アイデアは:時間を超えているので、暴力的、半暴力的なソリューションの使用(自家製名詞ハッハッハ)に、完全なソリューションを開始します。これは、大量のデータセットに起因して、我々は部分ごとに維持する必要がありますので、我々は、すべての配列でそれを維持することはできません。百のドリフト奇妙な与えられた数を決定することから始め、その数は112で、これは第二部では数であることを前に、私はそれを明確に持っている場合、私は知らないが、問題はおそらく意味され、3などに所属する一部の数であります江紫。この項の図その数を超える判断力、そして最終的には結果の後にこの初期の判断。

私はあまりにも複雑書くので、最初はデジタルのどの部分を決定し、時間を超えて、私は数字で直接だっnは元の数を減算するインクリメントされています。

//错误代码
scanf("%d",&x);
            j=1;
            while(x>0){
                if(j<10){
                    n++;
                    x-=n;
                    j++;
                }
                else if(j<100&&j>9){
                    n+=2;
                    x-=n;
                    j++;
                }
                else if(j>99&&j<1000){
                    n+=3;
                    x-n;
                    j++;
                }
                else if(j>999&&j<10000){
                    n+=4;
                    x-n;
                    j++;
                } 
                else if(j>9999&&j<100000){
                    n+=5;
                    x-n;
                    j++;
                }
            }
            x+=n;

特に巧妙されていないが、私は少し改善された後に、この部分は、時間を超えて問題が、解決されます。私は実際には、概念はまだ非常にあいまいなアルゴリズムの時間計算量で、あまりにも鶏肉料理でした。

//正确代码
for(i=0;i<32000;i++)
        {   y=i;
            if(i==0)a[i]=1;
            else a[i]=a[i-1]+(int)(log10(y+1)+1);
            
        }//存位数 
for(j=0; ;j++)
            {
            x-=a[j];
            if(x<=0)break;
                }
        x+=a[j];

他の学生によるブログ、データセットまでの31268の合計、私は10万未満に拡大し100未満の裏、によって判断されますので、それは以下の特定の桁のコードを決定することです。

 j=1;
for(r=0; ;j++)
                                {
                    if(j<10){
                        n=j;
                        
                        r++;
                        if(r==x)break;
                    }
                    else if(j>9&&j<100){
                        n=j/10;
                    
                        r++;
                        if(r==x)break;
                        n=j%10;
                        r++;    if(r==x)break;  
                    }
                    else if(j>99&&j<1000)
                        {
                            n=j/100;
                        
                           r++;if(r==x)break;
                            n=j/10%10;
                        
                            r++;if(r==x)break;
                            n=j%10;
                            r++;if(r==x)break;
                        
                            
                        }
                    else if(j>999&&j<10000)
                        {
                            n=j/1000;
                                
                            r++;if(r==x)break;
                            n=j%1000/100;
                                
                            r++;if(r==x)break;
                            n=j%100/10;
                        
                            r++;if(r==x)break;
                            n=j%10;
                            r++;if(r==x)break;      
                        }
                    else if(j>9999&&j<100000)
                        {
                            n=j/10000;
                            r++;if(r==x)break;
                            n=j%10000/1000;
                            r++;if(r==x)break;
                            n=j%1000/100;
                            r++;if(r==x)break;
                            n=j%100/10;
                            r++;if(r==x)break;
                            n=j%10;
                            r++;if(r==x)break;      
                        }
                }
            printf("%d\n",n);

迷路

あなたは、迷路ゲームをプレイしている、N×Nのグリッドを有する迷路は、各セルは、0又は1が、隣接するセルの4フレームに一つのセルから移動させることができる数を有しています。時間を殺すために、あなたがプレイを変更する、我々は唯一の0から1へ行くか、1から0に行ったことができます。
今、あなたの開始点を与えるために、あなたはグリッドから(それ自身を含む)どのように多くのスターティンググリッドを計算する上に移動することができます。
入力フォーマット:
1行目は、2つの正の整数nとm(1≤n≤1000,1≤m≤10000)を含みます。
次のn行、nは迷路に対応する行、N行ごとに文字、文字間のスペースなし文字0又は1、。
次のm行、手段が求めメートル。i、jは、迷路からグリッド開始歩行の第i行j列を表し、各行2つの正の整数です。
出力フォーマット:
可動グリッドの最大数、所与の出力コモンmライン、各整数、それぞれ入力データをm回クエリに対応します、。

输入样例:
2  2
01
10
1  1
2  2
输出样例:
4
4

この質問は聞かせているので、私は私のアイデアの質問のように種類とは接触は一つ一つを見つけることではありません開始するために、このブログは、実際に、今日まで延期終え、はい、はい、江Ziが動作しません。DFSとBFSを理解するための情報へのアクセスで非常に多くの時間が、実際には、私は徹底的に理解し、今この問題に対処するやっとませんでした。このトピックの元のタイトルP1141 01迷路とこれに同梱問題解決の。アップメインビデオはまた、DFSがより良い彼の個人的な感情を入れて、DFSとBFSを理解するのに役立ちます。
気持ちは何も言うことはありませんので、問題解決には主に、(再帰によって達成)、DFSを使用しているため、一部のノートと問題解決のアイデアは、私は、コード内で直接それらをマークします。

#include<stdio.h>
#include<string.h>
int n,b[1005][1005],z[100005],i;//z数组是存每一个能够走的最大距离,需要开得大一点,不然会出现RE的问题
char s[1005][1005];
void dfs(int x,int y,int f);
int main()
{
    int m,c,d;
    scanf("%d%d",&n,&m);
    for(i=0;i<n;i++)
        {
            scanf("%s",s[i]);//一开始用%c来存,一直输出不了,应该是因为一行之间的0或1没有其他字符隔开,无法判断输出结束了吧
        }
    memset(b,-1,sizeof(b));//将b数组初始化为-1,这为了判断是否有走过这一格的数组。一开始初始化为0,但是当i=0时这个就没法走了[哭脸]
    for(i=0;i<m;i++)
        {
            scanf("%d%d",&c,&d);
            c--;
            d--;
            if(b[c][d]==-1)dfs(c,d,s[c][d]-48);//将字符数组转换为0和1比较方便于判断
            else z[i]=z[b[c][d]];//如果b数组已经被赋值,说明已经走过了这个各自,可以通过已经存储在a中的数字来读出,可以节省时间
            
        }
    for(i=0;i<m;i++)
        {
            printf("%d\n",z[i]);
        }
    return 0;
}
void dfs(int x,int y,int f)
{
    if(x<0||x>=n||y<0||y>=n)return;//判断是否在迷宫范围内; 
    else{
        if(b[x][y]==-1&&s[x][y]-48==f){//判断该格子是否走过且是否与上一个格子的字符相同
            b[x][y]=i;
            z[i]++;
            dfs(x+1,y,!f);//这个!f得想一想,就是取上一个格子的字符的相反数,体现了将字符元素改为0和1的好处了吧
            dfs(x-1,y,!f);
            dfs(x,y+1,!f);
            dfs(x,y-1,!f);
        }
        else return;
    }
    
}

ひどくそこに書かれたか、間違った場所に言われた場合は、ああすることを歓迎します。

おすすめ

転載: www.cnblogs.com/ponynice/p/12521121.html