試題一 洗牌重排
牛牛有13張撲克牌,數字分别為1-13,現在他有這樣的洗牌方法:此時他手上的牌按照從上到下的順序排列,他每次選擇任意數量的牌放在左手,其他的牌放在右手。之後,他将左手最下面一張放在最下面,右手最下面一張放在它的上面,左手倒數第二張和右手倒數第二張依次摞在上面,以此類推,當一隻手上沒有牌時,就将另一隻手上的牌按序直接放在新的牌堆上。問經過若幹次操作,新牌堆從上至下的牌序是什麼?
輸入:
1 2 3 4 5 6 7 8 9 10 11 12 13
2
6 1
輸出:
8 1 9 2 10 3 11 4 12 5 13 6 7
說明:
1.輸入第一行表示原始牌堆從上到下的牌序(不一定是遞增),第二行表示操作次數,第三行表示每次操作把多少張牌放在左手
2.輸出的結果最後一項沒有空格
舉例:
如上述輸入,第一次将上面6張牌(123456)放在左手,其餘放在右手。按照規則,先将6放在最下面,再将13放在6的上面,後将5放在13的上面,再将12放在5的上面......以此類推,最後右手隻剩7,直接放在最上面。此時牌序從上而下為
7 8 1 9 2 10 3 11 4 12 5 13 6
這道題其實思路很簡單,就是每次将13張牌分成兩組,設定兩個指針,分别從後向前掃,依次将兩組元素插入新數組,最後把新數組中的值賦給原始數組,以操作數為循環條件,每次操作結束後清空兩組值。這裡為了友善,我選取vector來存儲。
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> A;//用于存儲原始牌序
int s;
for(int i=0;i<13;i++){
cin>>s;
A.push_back(s);
}
int N,t;//N:操作數
vector<int> T;//用于存儲每次操作放在左手上的牌的數量
cin>>N;
for(int i=0;i<N;i++){
cin>>t;
T.push_back(t);
}
vector<int> top,below;//top:左手上的牌,below:右手上的牌
int output[13]={0};//output:輸出
int m=0;
while(N){
int k=12;
for(int i=0;i<T[m];i++){
top.push_back(A[i]);
}
for(int i=T[m];i<13;i++){
below.push_back(A[i]);
}
int p=top.size()-1,q=below.size()-1;
while(p<q){//上面少
if(p>=0){
output[k--]=top[p];
output[k--]=below[q];
p--;
q--;
}
else{
if(q>=0){
output[k--]=below[q];
q--;
}
}
}
while(p>q){//下面少
if(q>=0){
output[k--]=top[p];
output[k--]=below[q];
p--;
q--;
}
else{
if(p>=0){
output[k--]=top[p];
p--;
}
}
}
N--;
m++;
top.clear();
below.clear();
A.clear();
for(int i=0;i<13;i++){
A.push_back(output[i]);
}
}
for(int i=0;i<12;i++){
cout<<A[i]<<" ";
}
cout<<A[12];
}
結果顯示:
試題二 三個整數
現有三個正整數a,b,c,隻能對它們做出如下兩種操作:
1. 選擇其中兩個,将它們都加1;
2. 選擇其中一個,将它加2。
通過若幹次操作,一定能讓這三個整數相等。求最少的操作次數。
輸入:
2 5 4
輸出:
2
這道題就是純數學計算,一般想法是分類讨論,比較三個正數的奇偶性,我的思路更為簡潔。對三個正數排序,每次隻将最小的數加2,直到最小的數和中間那個數相等。再同時加1,直到三數相等。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
vector<int> s;//用于存儲三數
int tmp,count=0;
for(int i=0;i<3;i++){
cin>>tmp;
s.push_back(tmp);
}
sort(s.begin(),s.end());
while(1){
while(s[0]!=s[1]){
s[0]+=2;
count++;
sort(s.begin(),s.end());//每次都必須排序!
}
if(s[0]==s[1]){
if(s[1]==s[2]){
cout<<count;
break;//必須break,否則會死循環!
}
else{
while(s[1]<s[2]){
s[0]++;
s[1]++;
count++;
}
}
}
}
}
結果顯示:
試題三 糕點拼盤
牛牛有三種糕點,分别是甜(T)、苦(K)和酸(S)。現在将三種糕點拼盤為糕點盒,每盒裝三個糕點。每盒至多裝一個苦糕點,每盒至多裝一個酸糕點,且苦和酸糕點不能同時裝在一個糕點盒裡,否則會産生黑暗糕點。問最多能裝幾個糕點盒?
輸入:
4 2
T K K S
2 4
3 4
輸出:
說明:
1.第一行有兩個整數:第一個N表示糕點總數,第二個M表示能産生黑暗糕點的配對數。
2.第二行表示糕點的種類,共有N個。
3.後面M行表示第二行中對應的糕點下标會産生黑暗糕點的配對,如2是K,4是S,它們會産生黑暗糕點。
4.輸入保證将所有的下标配對列出并不存在重複。
這道題其實輸入的M行配對是無用資訊,關鍵在于三種糕點的數量,要進行四類情況讨論:
1. 隻有T
2. T<=2*min(K,S)
3. T>2*min(K,S),且T-2*min(K,S)<=2*max(K,S)
4. T>2*min(K,S),且T-2*min(K,S)>2*max(K,S)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
vector<char> s;
int N,M;
int a,b;
char tmp;
cin>>N>>M;
for(int i=0;i<N;i++){
cin>>tmp;
s.push_back(tmp);
}
for(int i=0;i<M;i++){
cin>>a>>b;
}
int Tcount=0,Kcount=0,Scount=0;
for(int i=0;i<N;i++){
if(s[i]=='T') Tcount++;
if(s[i]=='K') Kcount++;
if(s[i]=='S') Scount++;
}
if(Kcount==0 && Scount==0) cout<<Tcount/3;
if(Kcount>0 || Scount>0){
if(Kcount<Scount){
if(Tcount<=2*Kcount) cout<<Tcount/2;
else{
if(Tcount-2*Kcount<2*Scount) cout<<Tcount;
else cout<<Kcount+Scount+(Tcount-2*Kcount-2*Scount)/3;
}
}
if(Kcount>=Scount){
if(Tcount<=2*Scount) cout<<Tcount/2;
else{
if(Tcount-2*Scount<2*Kcount) cout<<Tcount;
else cout<<Kcount+Scount+(Tcount-2*Kcount-2*Scount)/3;
}
}
}
}
結果顯示:
版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。https://blog.csdn.net/qq_34563932/article/details/80014804