演習1-再帰など

1000問題A

制限時間:40/20 MS(Java /その他)|メモリ制限:65536/32768 KB(Java /その他)

提出:110 | 解決済み:24

タイトル説明

順序付けられていない値のセットが与えられた場合、値のサイズは100万から100万の間であり、値の数は100,000から500,000の間です。次に、5番目から10番目に小さい整数を見つける必要があります。

入力要件

ゼロ以外の整数のグループ(数値> = 10)、0は終了記号です。

出力要件

5番目から10番目に小さい整数。各出力は整数で折り返されます。

入力サンプル

1
2
3
4
5
6
7
8
9
10
0

サンプル出力

5
6
7
8
9
10

// An highlighted block
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
    
    
	int a[5000];
	int i=0;
	int x;
	while(cin>>x){
    
    
		if(x==0) break;
		a[i++]=x;

	}
	sort(a,a+i-2);
	for(i=4;i<10;i++){
    
    
		cout <<a[i]<<endl;
	}
	return 0;
}

1001問題B

制限時間:2000/1000 MS(Java /その他)|メモリ制限:65536/32768 KB(Java /その他)

提出:55 | 解決済み:7

タイトル説明

2行N列の歩道用。次に、12または22個のレンガを使用して埋めます。いくつの異なる方法を尋ねます(解決するには再帰を使用してください)。Nが大きい場合は、高精度の計算が必要です。下の写真は、2行17列の歩道の特定の舗装方法です。

ここに写真の説明を挿入

入力要件

整数N、N <= 1000。

出力要件

全部でいくつの方法がありますか?

入力サンプル

30

サンプル出力

715827883

分析

1大きな整数の追加には文字列を使用します
。2タイル配置の問題:
タイルを配置するたびに考慮事項はほぼ同じであるため、再帰によって解決できます。残りの列の数に応じて、この質問を2つの状況に分けます。

A:最後の列が残っているので、この列を削除した後、タイル化された状況がn-1の状況と同じであり、追加した後、状況が1つしかないため、メソッドはpave(n-1)であるとします。

B:末端に2つの残りの列があり、その後、最初の2つの列を削除して状況がn-2と同じであり、これらの2つの列を追加した後、3つの状況がある:1 2 1、2列に垂直に配置される2が水平に配置され、そして2 2直接記入してください。1 2は垂直に配置され、Aと重なるため、メソッドの数はpave(n-2)* 2になります。

要約すると、メソッドの総数= pave(n-1)+ 2 * pave(n-2
ここに写真の説明を挿入

// An highlighted block
#include<iostream>
#include <algorithm>
#include<string>
using namespace std;
//用string实现大整数加法
string myadd(string a,string b){
    
    
	reverse(a.begin(),a.end());//字符串翻转
	reverse(b.begin(),b.end());
	int len;
	if(a.length()>b.length()){
    
    
		len=a.length(); //记录长的长度
		while(b.length()==len) b+=" ";//末尾补齐
	}else{
    
    
		len=b.length(); 
		while(a.length()==len) a+=" ";
	}
	int i=0,t=0;
	string ans;
	while(i<len){
    
    
		t+=a[i]-'0'+b[i]-'0';
		ans+=(t%10+'0');//拼接
		t/=10;
		i++;
	}
	if(t>0) ans+=t+'0';//进位加上
	reverse(ans.begin(),ans.end());
	return ans;
}

int main(){
    
    
	int n;
	string dp[1200];
	dp[0]="1";
	dp[1]="1";
	dp[2]="3";
	for(int i=3;i<=1000;i++){
    
    
		dp[i]=myadd(dp[i-1],myadd(dp[i-2],dp[i-2]));
	}
	while(cin>>n){
    
    	 
		cout<<dp[n]<<endl;
	}
	return 0;
}

1002問題C

制限時間:2000/1000 MS(Java /その他)|メモリ制限:65536/32768 KB(Java /その他)送信
:56 |解決済み:11

タイトル説明

N×Nブロック、左上隅は[1,1]、右下隅は[N、N]、(N <100)です。上下または右にしか行けないたびに、左上隅から右下隅までのパスの総数を見つける必要があります。

パスには障害物(M <10)のあるMブロックがあり、通過できませんが、終点に到達できない状況にはなりません。

データのオーバーフローを回避するには、各道路のパスの総数を10,000にする必要があります。

入力要件

最初の行:2つの整数NとM;それぞれブロックの寸法と障害物の数を表します。

2行目は、障害物が配置されているブロックであるM行で始まります。

出力要件

質問の意味を満たすパスの数を出力します。

入力例
3 1
3 1

サンプル出力
5
ここに写真の説明を挿入

// An highlighted block
# include<iostream>
using namespace std;
int dp[101][101];  // 保存走到每个街区的路数

int main()
{
    
    
	for(int i=0;i<=100;i++)
		for(int j=0;j<=100;j++)
			dp[i][j] = 1;
	int n,m;  // 街区的维数和障碍数
	cin >> n >> m;
	while(m--)  // 将每个有障碍的街区置为0 
	{
    
    
		int a, b;
		cin >> a >> b;
		dp[a][b] = 0;
	}
	for(int i=1; i<=n; i++)
		for(int j=1; j<=n; j++)
		{
    
    
			if(dp[i][j] != 0)  //不考虑已经被置为0的有障碍的街区 
			{
    
    
				if(i==1 && j!=1)  // 给第一行街区赋值,不包括初始位置 
					dp[i][j] = dp[i][j-1];
				else if(i!=1 && j==1)  // 给第一列街区赋值,不包括初始位置
					dp[i][j] = dp[i-1][j];
				else if(i!=1 || j!=1)  //除初始位置的其他位置 
					dp[i][j] = (dp[i][j-1] + dp[i-1][j]) % 10000 ; // 每个街区的路径数为左边街区的路径数和上方路径数之和 
			}
		}
	 
	cout << dp[n][n] << endl; 
	return 0;
}

おすすめ

転載: blog.csdn.net/weixin_40852935/article/details/109170163