(文字列の処理)Blue Bridge Cup 2013 C /C++グループA州大会Zhenti7エラーノート

トピック

シークレット関連のユニットが何らかの請求書を発行しましたが、これは年末に回収される予定です。

各チケットには一意のID番号があります。年間を通してすべてのノートのID番号は連続していますが、IDの開始番号はランダムに選択されます。

スタッフの過失により、ID番号の入力時にエラーが発生し、あるIDのIDが壊れ、別のIDのIDが重複していました。

あなたの仕事は、プログラムでブレーク番号のIDとダブル番号のIDを見つけることです。

ブレーク番号は、最大数と最小数では発生しないと想定されています。

プログラムは、最初に整数N(N <100)を入力して、後続のデータ行の数を表す必要があります。
  次に、N行のデータを読み込みます。
  データの各行の長さはさまざまで、スペースで区切られた(100以下の)正の整数(100,000以下)の数です。
  各整数はID番号を表します。

プログラムは、スペースで区切られた2つの整数mnを含む1行を出力する必要があります。
  その中で、mはブレークIDを表し、nはリピートIDを表します。

例:
  ユーザー入力:
  2
  5 6 8 11 9
  10 12 9

次に、プログラム出力:
  7 9

  別   の例:
  ユーザー   入力   :
  6164178108109180155141159104182171125129168196172189127107112192103131133169158128102110148139157140195197185152135106123173122136 1511431751201611341621901491381421461993193144166170121171132101194187188113130176154177120117150114183186181100163160167147198111119   _   _





次に、プログラム出力:
  105 120

リソースの規則:
  ピークメモリ消費量<64MCPU
  消費量<1000ms

要件に厳密に従って出力し、「入力してください...」のような余分なコンテンツを表面的に印刷しないでください。

すべてのコードは同じソースファイルに配置され、デバッグ後、ソースコードをコピーして送信します。

注:main関数は0を返す必要があります。
  注:ANSI C / ANSI C ++標準のみを使用し、コンパイル環境またはオペレーティングシステムに依存する特別な関数を呼び出さないでください。
  注:すべての依存関数はソースファイルに明示的にインクルードする必要があり、プロジェクト設定で共通のヘッダーファイルを省略することはできません。

送信するときは、目的のコンパイラタイプを選択するように注意してください。

分析する

質問の意味を解釈します。n、n行のデータが与えられた場合、データの各行は必​​ずしも数で構成されているとは限りません。データ全体の中で、1つの場所に不連続性があり、数が繰り返されます。これらの2つのうち数は何ですか。

一見、この質問は比較的単純です。直接並べ替えた後、ループでトラバースできますが、彼から提供されたデータをどのように入力するのでしょうか。各行のデータ量がわからないため、それに対処するのは難しい。

コードセクション

1.初期化して、次のように入力します

最初にn、次に文字列の配列がn行ずつ入力されます

	int n;
	cin>>n;
	vector<string> str(n);

	getchar();

	for(int i=0;i<n;i++)
		getline(cin,str[i])
2.入力を処理し、文字列を数値に変換します

外側のループはn回で、毎回データの行を変換し、左端と右端をそれぞれ設定します。左端は現在の番号の最初の文字にあり、右端は現在の番号の後のスペースにあります。使用この文字列を文字列に渡すsubstr関数デジタル処理の関数を変換してから、左右の端点を更新します。最後の数値の後にスペースがないことに注意してください。特別な判断を下すには、長さを追加するだけです。制限として現在の文字列全体の。

	int cnt=0;			//记录数字的个数 
	for(int i=0;i<n;i++)
	{
    
     
		int l=0,r=0;	//左端点右端点
		while(r<str[i].size())		//把每行的各个数字转换 
		{
    
    
			while(str[i][r]!=' '&&r<str[i].size())
				r++;
			s_to_i(cnt,str[i].substr(l,r));
			
			++r;
			l=r;
			++cnt;
		}
	}
3.文字列を数値に変換する関数

stringstreamを使用して文字列を数値に変換する

void s_to_i(int i,string str)
{
    
    
	stringstream ss;
	ss<<str;
	ss>>a[i];
}
4.配列をループして、最終的な答えを見つけます

ここでは、配列を並べ替えた後の処理がはるかに簡単になります。繰り返される要素は隣り合っているため、並べてある数字を判断するだけで済みます.2つの値が等しい場合、答えは答えです。欠落しているデータは、前後の2つの数字の差が2であり、次に前の数字であるということです。通常、音符は連続しているため、数字に1を加えたものが答えです。

	sort(a,a+cnt);
	
	int ans1;		//少的id
	int ans2;		//重复id
	
	for(int i=0;i<cnt-1;i++)
	{
    
    
		if(a[i]==a[i+1])
			ans2=a[i];
		if(a[i+1]-a[i]==2)
			ans1=a[i]+1;
	}

完全なコード

#include <bits/stdc++.h>
using namespace std;

int a[10000];		//存放所有数字 

void s_to_i(int i,string str)
{
    
    
	stringstream ss;
	ss<<str;
	ss>>a[i];
}

int main (void)
{
    
    
	int n;
	cin>>n;
	vector<string> str(n);

	getchar();

	for(int i=0;i<n;i++)
		getline(cin,str[i]);
	
	int cnt=0;			//记录数字的个数 
	for(int i=0;i<n;i++)
	{
    
     
		int l=0,r=0;	//左端点右端点
		while(r<str[i].size())		//把每行的各个数字转换 
		{
    
    
			while(str[i][r]!=' '&&r<str[i].size())
				r++;
			s_to_i(cnt,str[i].substr(l,r));
			
			++r;
			l=r;
			++cnt;
		}
	}
	
	sort(a,a+cnt);
	
	int ans1;		//少的id
	int ans2;		//重复id
	
	for(int i=0;i<cnt-1;i++)
	{
    
    
		if(a[i]==a[i+1])
			ans2=a[i];
		if(a[i+1]-a[i]==2)
			ans1=a[i]+1;
	} 
		
	cout<<ans1<<" "<<ans2;
	
	return 0;
	
} 

要約する

この問題の難しさは、入力の処理、文字列の処理、および数値への分割にあります。
文字列のさまざまな機能と文字列ストリームの機能に精通している場合、この問題ははるかに簡単になります。

おすすめ

転載: blog.csdn.net/weixin_46035615/article/details/123821768