FZU ICPC 2020冬のトレーニング4 - アナログ(B)

P1056シート行

タイトル説明

クラスは常にお互いにささやく学生や人々についてのいくつかの前後にある場合には、小学校の教師になる何かが非常に面倒なことです。座席の学生が確定したときしかし、雪の先生が、いくつかの興味深い現象を発見し、限られたDは、クラスの時に学生をささやくます。教室の学生は、M行N列に座っているであろう、第i行j列目の位置に座っている学生は、(i、j)は、学生を容易にするために、L、教室でK横チャネルを提供縦方向のチャンネルストリップ。
だから、スマート雪がお互いにささやくクラスの生徒の、おそらく問題は低減することができ、方法を考えた:1つのチャネルは2意志を分離した場合ので、彼女は学生との間のチャネルの位置を変更するためにテーブルと椅子、テーブルと椅子を再配置する予定でささやきます学生、彼らはないささやきだろう。
あなたは最高のチャネル分割方式を与え、雪にプログラムを書いてくださいだろう。このスキームの下では、クラスの生徒の最小数はささやきます。

入力形式

5つの整数スペース、それぞれM、N、K、L、によって分離された第1ライン、 D(2≤N、M≤1000,0≤K<M、0≤L<N、D≤2000) D次の行は、4つのスペースを有し、各列は、整数によって分離されました。二人の学生のI番目の行4つの整数Xiの、李、PI、チー、着座位置(XI、李)を示すと(PI、チー)(これらはすべての周りの隣接または近隣に入ることを確実にするために)ささやくう。
最適解の一意性を確保するために、入力データ。

出力フォーマット

2つのラインの合計。最初の行はKの整数A1、A2、...、AK、A​​1は第一のラインとラインA2 + 1、...、AK 1行AK + 1の最初の行との間の最初の行とA1 + 1、A2の間の行を表す含まここで、との間の道を開くには空間(行間隔の終わり)で区切られた各2つの整数の間に、+ 1を愛<愛。
2行目は、最初の行B1及びB1 + 1列BLとの間に第一列およびB2 B2 + 1行との間のL整数B1、B2を、... ,,含まbLを+ 1、...、bLを最初の列と最初の行を表します各2つの整数の間、ここで双1 + <BIとの間の道を開くには空間(スペースなしのEOT)によって分離しました。

入力#1

4 5 1 2 3
4 2 4 3
2 3 3 3
2 5 2 4

出力#1

2
2 4

説明/ヒント


記号*によって上図は、※、+生徒の3対の位置をささやきであろうマーク、図太い線は、チャネル3の位置を示し、チャネル分割方式は、最適なソリューションが示されています。

受理
出典:羅区

//只要找出划分哪些相邻的两行和相邻的两列可以隔开的同学最多,此题可解。
#include <stdio.h>
#include <math.h>
#include <string.h>
int min(int a,int b){
    if(a>b) return b;
    else return a;
}
    int main(){
        int m,n,k,l,d;
        int xi,yi,pi,qi;
        int i,j;
        int x[1006]={0},y[1006]={0};//x列,y行
        int c[1006]={0},o[1006]={0};
        scanf("%d %d %d %d %d",&m,&n,&k,&l,&d);
        for(i=1;i<=d;i++){
            scanf("%d %d %d %d",&xi,&yi,&pi,&qi);
            if(xi==pi) x[min(yi,qi)]++;//表示隔开这两排的价值
            else y[min(xi,pi)]++;//记得取min,即过道与前一个坐标保持一致
        }
        for(i=1;i<=k;i++){
            int max=-1;//为了求出每次的最大值,需要每次扫一遍
            int p;
            for(j=1;j<m;j++){
                if(y[j]>max){
                    max=y[j];
                    p=j;
                }
            }
            y[p]=0;//求出max之后一定要记得清零!!否则无论排多少次都是一个答案
            c[p]++;
        }
        for(i=1;i<=l;i++){
            int max=-1;
            int p;
            for(j=1;j<n;j++){
                if(x[j]>max){
                    max=x[j];
                    p=j;
                }
            }
            x[p]=0;
            o[p]++;
        }
        for(i=0;i<1005;i++){
            if(c[i]) printf("%d ",i);
        }
        printf("\n");
        for(i=0;i<1005;i++){
            if(o[i]) printf("%d ",i);
        }
        return 0;
    }

P1098の文字列展開

タイトル説明

、入力文字列ならば、同様の「DH」または「4-8」の文字列を含む:グループの人気の予備的な質問では、展開我々は、文字列の例を与えている「読者の結果が書きました」我々は、出力、文字や数字の連続列が前記マイナス記号、即ち、の出力は、2つのサブストリング「defgh」と「45678」は、上記それぞれの代替インクリメントそれ短い考えます。この問題では、我々はより柔軟な文字列の拡張の数を増やすことでパラメータを設定します。次のように具体的な規則は、次のとおりです。

(1)文字列を拡張するために行われる次のニーズを満たす:入力文字列で、マイナス表示されます「 - 」、小文字または数字で両側にマイナス記号、およびASCIIコードの順で、左側の文字よりも厳密に大きいマイナスの右にある文字。

(2)パラメータp1:方法を展開します。p1=1文字の部分文字列のため、小文字が満たされた場合には、; p1=2とき、文字を大文字いっぱいSUBSTRING。どちらの場合も部分文字列の同じ数はモードを埋めます。p1=3ときは、数字の文字列の部分文字列のいずれかの文字や、文字はアスタリスクの数が同じで満たされるために使用されて*充填されます。

(3)パラメータp2:パッドの文字の数が繰り返されます。p2=kkの連続充填する同じ文字を表します。たとえば、ときp2=3、部分文字列をd-h拡張する必要がありますdeeefffgggh変わらないの両側にマイナス文字。

(4)パラメータp3:彼らが逆転する場合:p3=1元の順序を維持表し、p3=2この時間はまだあるマイナス記号が含まれていない、文字の両端に注意を払うを逆出力を使用することを示しています。たとえばときp1=1p2=2p3=2、ストリングはd-h延長すべきですdggffeeh

(5)左のマイナス記号の右側の文字には、例えば、単にマイナス記号の真ん中を削除し、文字の後継者であることを起こる場合は、次のd-e出力がなければならないde3-4出力する必要があります34例えば、中間マイナス記号を保持するために、左マイナス以下の文字、ASCII出力コードの右側の文字が場合:d-d出力されるようにd-d3-1出力する必要があります3-1

入力形式

2つのラインの合計。
最初の動作は、パラメータP1、P2、P3のそれぞれについて、3つの正の整数のスペースで区切られました。
第2の行線ストリング、数字のみ、小文字とマイナス組成物。行の最後なしラインスペースで。

出力フォーマット

総行、膨張の文字列の後。

入力#1

1つの2 1
いろは-w1234-9s-4zz

出力#1

abcsttuuvvw1234556677889s-4zz

入力#2

2 3 2
アドオン

出力#2

aCCCBBBd-D

受理
出典:羅区

実際にはこの問題は難しいことではありませんが、その後の状況、問題の解決策を見ているときに表示する方法を分割し、複数のループを使用するために、コードは非常に簡潔であり、また、使用上のCおよびC ++の間に別の違いを発見します

//三目运算符来少写几个for循环让代码变得简洁(c++)
#include <stdio.h>
#include <math.h>
#include <string.h>
    int main(){
        int p1,p2,p3;
        char str[1005];
        int len;
        char p;
        int j,k;
        scanf("%d %d %d",&p1,&p2,&p3);
        scanf("%s",str);
        len=(int)strlen(str);
        for(int i=0;i<len;i++){
if(str[i]=='-'&&str[i-1]<str[i+1]&&((str[i-1]>='0'&&str[i+1]<='9')||(str[i-1]>='a'&&str[i+1]<='z'))){
    for(p3==1?j=str[i-1]+1:j=str[i+1]-1;p3==1?j<str[i+1]:j>str[i-1];p3==1?j++:j--){
        p=j;
       if(p1==2)//是否大写
           p=(p>='a')?p-32:p;
       else if(p1==3) p='*';
        for(k=0;k<p2;k++) printf("%c",p);
            }
    }
       else printf("%c",str[i]);
        }
        return 0;
    }

おすすめ

転載: www.cnblogs.com/lvhang/p/12283403.html