2016年C語言混搭 C/C++

摘錄《讀者》片段以表達今日份感慨:

今天的小魚吃飽喝足後依舊元氣滿滿呢!(就是——開學該減肥啦……)


1.報紙頁數

X星球日報和我們地球的城市早報是一樣的,
都是一些單獨的紙張疊在一起而已。每張紙印有4版。

比如,某張報紙包含的4頁是:5,6,11,12,
可以確定它應該是最上邊的第2張報紙。

我們在太空中撿到了一張X星球的報紙,4個頁碼分別是:
1125,1126,1727,1728

請你計算這份報紙一共多少頁(也就是最大頁碼,並不是用了幾張紙哦)?

請填寫表示總頁數的數字。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。
 

#include<iostream>
using namespace std;
int main(){
	for(int i=1125,j=1727;i>0;){
		cout<<i<<' '<<i+1<<' '<<j<<' '<<j+1<<endl;
		i-=2;j+=2;
	}
	return 0;
}

 

 


2.網友年齡

某君新認識一網友。
當問及年齡時,他的網友說:
“我的年齡是個2位數,我比兒子大27歲,
如果把我的年齡的兩位數字交換位置,剛好就是我兒子的年齡”

請你計算:網友的年齡一共有多少種可能情況?

提示:30歲就是其中一種可能哦.

請填寫表示可能情況的種數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

#include<iostream>
using namespace std;
int main(){
	int cnt=0,tmp;
	for(int i=27;i<=99;i++){
		tmp=(i%10)*10+i/10;
		if(i-tmp==27){
			cout<<i<<' '<<tmp<<endl;
			cnt++;
		}
	}
	cout<<cnt;
	return 0;
}

 

 

3.圓周率


歷史上有許多計算圓周率pai的公式,其中,格雷戈裏和萊布尼茨發現了下面的公式:

pai = 4*(1-1/3+1/5-1/7 ....)

參見【圖1.png】

這個公式簡單而優美,但美中不足,它收斂的太慢了。
如果我們四捨五入保留它的兩位小數,那麼:

累積了1項和是:4.00
累積了2項和是:2.67
累積了3項和是:3.47
。。。

請你寫出它累積了100項的和是多少(四捨五入到小數後兩位)。

注意:只填寫該小數本身,不要填寫任何多餘的說明或解釋文字。

#include<iostream>
#include<cstdio>
using namespace std;
int main(){
	int cnt=0;
	double PI=0;
	for(int mu=1,flag=1;cnt!=100;mu+=2){
		PI+=1.0*flag*4/mu;
		cnt++;
		flag=-flag;
		printf("%d: %.2lf\n",cnt,PI);
	}
	printf("%d: %.2lf\n",cnt,PI);
	return 0;
}

 

 

4.平方怪圈

如果把一個正整數的每一位都平方後再求和,得到一個新的正整數。
對新產生的正整數再做同樣的處理。

如此一來,你會發現,不管開始取的是什麼數字,
最終如果不是落入1,就是落入同一個循環圈。

請寫出這個循環圈中最大的那個數字。

請填寫該最大數字。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int cnt=0;
void deal(ll n){
	if(cnt==30) return;
	int sum=0;
	while(n){
		sum+=(n%10)*(n%10);
		n/=10;
	}
	cout<<++cnt<<": "<<sum<<endl;
	deal(sum);
}
int main(){
	for(int i=1;i<=1000;i++){
		cout<<"NO."<<i<<":"<<endl;
		cnt=0;
		deal(i);
		cout<<endl;
	}
	return 0;
}

 

 

5.打印方格

小明想在控制檯上輸出 m x n 個方格。
比如 10x4的,輸出的樣子是:
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+

(如果顯示有問題,可以參見【圖1.jpg】)

以下是小明寫的程序,請你分析其流程,填寫劃線部分缺少的代碼。


#include <stdio.h>

//打印m列,n行的方格 
void f(int m, int n)
{
    int row;
    int col;
    
    for(row=0; row<n; row++){
        for(col=0; col<m; col++) printf("+---");
        printf("+\n");
        for(col=0; col<m; col++) printf("|   ");
        printf("|\n");        
    }
    
    printf("+");
    for(col=0; col<m; col++) printf("---+");   //填空
    printf("\n");
}

int main()
{
    f(10,4);
    return 0;
}

 

 

6.搭積木

小明最近喜歡搭數字積木,
一共有10塊積木,每個積木上有一個數字,0~9。

搭積木規則:
每個積木放到其它兩個積木的上面,並且一定比下面的兩個積木數字小。
最後搭成4層的金字塔形,必須用完所有的積木。

下面是兩種合格的搭法:

   0
  1 2
 3 4 5
6 7 8 9

   0
  3 1
 7 5 2
9 8 6 4    

請你計算這樣的搭法一共有多少種?

請填表示總數目的數字。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[10]={0,1,2,3,4,5,6,7,8,9};
bool judge(int i,int j){
	return (a[i]<a[j]?1:0);
}
int main(){
	int cnt=0;
	do{
		if(!judge(0,1)||!judge(0,2)) continue;
		if(!judge(1,3)||!judge(1,4)||!judge(2,4)||!judge(2,5)) continue;
		if(!judge(3,6)||!judge(3,7)||!judge(4,7)||!judge(4,8)||!judge(5,8)||!judge(5,9)) continue;
		cnt++;
	}while(next_permutation(a,a+10));
	cout<<cnt;
	return 0;
}

 

 


7.寒假作業

現在小學的數學題目也不是那麼好玩的。
看看這個寒假作業:

   □ + □ = □
   □ - □ = □
   □ × □ = □
   □ ÷ □ = □
   
   (如果顯示不出來,可以參見【圖1.jpg】)


   


每個方塊代表1~13中的某一個數字,但不能重複。
比如:
 6  + 7 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

以及: 
 7  + 6 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

就算兩種解法。(加法,乘法交換律後算不同的方案)
 
你一共找到了多少種方案?


請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

調皮的數組下標把我害慘了……
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[13]={1,2,3,4,5,6,7,8,9,10,11,12,13};
int main(){
	int cnt=0;
	do{
		if(a[9]+a[10]!=a[11]) continue;
		if(a[6]-a[7]!=a[8]) continue;
		if(a[3]*a[4]!=a[5]) continue;
		if(a[0]==a[1]*a[2]) cnt++;
	}while(next_permutation(a,a+13));
	cout<<cnt;
	return 0;
} 
orz
#include<iostream>
using namespace std;
int a[13],vis[13];
int cnt=0;
void dfs(int step){
	if(step>3&&a[0]+a[1]!=a[2]) return;
	if(step>6&&a[3]-a[4]!=a[5]) return;
	if(step>9&&a[6]*a[7]!=a[8]) return;
	if(step>12&&a[9]==a[10]*a[11]){
		cnt++;
		return;
	}
	for(int i=0;i<13;i++){
		if(!vis[i]){
			vis[i]=1;
			a[step]=i+1;
			if(step<13) dfs(step+1);
			vis[i]=0;
		}
	}
}
int main(){
	dfs(0);
	cout<<cnt;
	return 0;
} 

 

 

 

 

8.冰雹數

任意給定一個正整數N,
如果是偶數,執行: N / 2
如果是奇數,執行: N * 3 + 1

生成的新的數字再執行同樣的動作,循環往復。

通過觀察發現,這個數字會一會兒上升到很高,
一會兒又降落下來。
就這樣起起落落的,但最終必會落到“1”
這有點像小冰雹粒子在冰雹雲中翻滾增長的樣子。

比如N=9
9,28,14,7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
可以看到,N=9的時候,這個“小冰雹”最高衝到了52這個高度。

輸入格式:
一個正整數N(N<1000000)
輸出格式:
一個正整數,表示不大於N的數字,經過冰雹數變換過程中,最高衝到了多少。

例如,輸入:
10
程序應該輸出:
52

再例如,輸入:
100
程序應該輸出:
9232

資源約定:
峯值內存消耗 < 256M
CPU消耗  < 1000ms

請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多餘內容。

所有代碼放在同一個源文件中,調試通過後,拷貝提交該源碼。

注意: main函數需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要調用依賴於編譯環境或操作系統的特殊函數。
注意: 所有依賴的函數必須明確地在源文件中 #include <xxx>, 不能通過工程設置而省略常用頭文件。

提交時,注意選擇所期望的編譯器類型。

答案錯誤40%版本:(待更新……)
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
int main() {
	int n,ans,tmp;
	cin>>n;
	ans=n;
	for(int i=n; i>0; i--) { //題意理解
		tmp=i; //很重要
		while(tmp!=1) {
			if(tmp&1) tmp=tmp*3+1;
			else tmp=tmp/2;
			ans=max(ans,tmp);
		}
	} 
	cout<<ans<<endl;
	return 0;
}

 

 

 

9.交換瓶子

有N個瓶子,編號 1 ~ N,放在架子上。

比如有5個瓶子:
2 1 3 5 4

要求每次拿起2個瓶子,交換它們的位置。
經過若干次後,使得瓶子的序號爲:
1 2 3 4 5

對於這麼簡單的情況,顯然,至少需要交換2次就可以復位。

如果瓶子更多呢?你可以通過編程來解決。

輸入格式爲兩行:
第一行: 一個正整數N(N<10000), 表示瓶子的數目
第二行:N個正整數,用空格分開,表示瓶子目前的排列情況。

輸出數據爲一行一個正整數,表示至少交換多少次,才能完成排序。

例如,輸入:
5
3 1 2 5 4

程序應該輸出:
3

再例如,輸入:
5
5 4 3 2 1

程序應該輸出:
2

資源約定:
峯值內存消耗(含虛擬機) < 256M
CPU消耗  < 1000ms


請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多餘內容。

所有代碼放在同一個源文件中,調試通過後,拷貝提交該源碼。
注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。
注意:主類的名字必須是:Main,否則按無效代碼處理。

#include<iostream>
#include<cstdio>
using namespace std;
int a[10005],pos[10005];
int main() {
	int n,cnt=0,tmp;
	cin>>n;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		pos[a[i]]=i;
	}
	for(int i=1;i<=n;i++){
		if(a[i]!=i){
			tmp=a[i];
			a[i]=a[pos[i]];
			a[pos[i]]=tmp;
			cnt++;
		}
	}
	cout<<cnt;
	return 0;
}

 

 

10.密碼脫落(最長公共子序列+非連續)

X星球的考古學家發現了一批古代留下來的密碼。
這些密碼是由A、B、C、D 四種植物的種子串成的序列。
仔細分析發現,這些密碼串當初應該是前後對稱的(也就是我們說的鏡像串)。
由於年代久遠,其中許多種子脫落了,因而可能會失去鏡像的特徵。

你的任務是:
給定一個現在看到的密碼串,計算一下從當初的狀態,它要至少脫落多少個種子,纔可能會變成現在的樣子。

輸入一行,表示現在看到的密碼串(長度不大於1000)
要求輸出一個正整數,表示至少脫落了多少個種子。

例如,輸入:
ABCBA
則程序應該輸出:
0

再例如,輸入:
ABDCDCBABC
則程序應該輸出:
3

資源約定:
峯值內存消耗 < 256M
CPU消耗  < 3000ms

請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多餘內容。

所有代碼放在同一個源文件中,調試通過後,拷貝提交該源碼。

注意: main函數需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要調用依賴於編譯環境或操作系統的特殊函數。
注意: 所有依賴的函數必須明確地在源文件中 #include <xxx>, 不能通過工程設置而省略常用頭文件。

提交時,注意選擇所期望的編譯器類型。

解法:求該字串與其反轉字符串非連續的最長公共子序列

借鑑cg代碼:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int dp[1005][1005];
int main(){
	string s1,s2;
	cin>>s1;
	s2=s1; //先複製再反轉啊,照葫蘆畫成梨啦,大寫的尷尬 
	reverse(s1.begin(),s1.end());
	int len=s1.size();
	for(int i=1;i<=len;i++)
	for(int j=1;j<=len;j++)
		if(s1[i-1]==s2[j-1]) 
			dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
		else 
			dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
	cout<<len-dp[len][len]<<endl;
	return 0;
}

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章