1. 程式人生 > 實用技巧 >PAT-Basic1-10

PAT-Basic1-10

【1001】害死人不償命的(3n+1)猜想

卡拉茲(Callatz)猜想:

對任何一個正整數 n,如果它是偶數,那麼把它砍掉一半;如果它是奇數,那麼把 (3n+1) 砍掉一半。這樣一直反覆砍下去,最後一定在某一步得到 n=1。卡拉茲在 1950 年的世界數學家大會上公佈了這個猜想,傳說當時耶魯大學師生齊動員,拼命想證明這個貌似很傻很天真的命題,結果鬧得學生們無心學業,一心只證 (3n+1),以至於有人說這是一個陰謀,卡拉茲是在蓄意延緩美國數學界教學與科研的進展……

我們今天的題目不是證明卡拉茲猜想,而是對給定的任一不超過 1000 的正整數 n,簡單地數一下,需要多少步(砍幾下)才能得到 n=1?

輸入格式:

每個測試輸入包含 1 個測試用例,即給出正整數 n 的值。

輸出格式:

輸出從 n 計算到 1 需要的步數。

輸入樣例:3

輸出樣例:5

#include<iostream>

using namespace std;

int main()

{

  int n;

  cin>>n;

  for(int i=0;n!=1;i++)

  {

    if(n%2)

      n=(3*n+1)/2;

    else

      n/=2;

  }

  cout<<i<<endl;

  return 0;

}


【1002】寫出這個數

讀入一個正整數 n,計算其各位數字之和,用漢語拼音寫出和的每一位數字。

輸入格式:

每個測試輸入包含 1 個測試用例,即給出自然數 n 的值。這裡保證 n 小於 10^100​。

輸出格式:

在一行內輸出 n 的各位數字之和的每一位,拼音數字間有 1 空格,但一行中最後一個拼音數字後沒有空格。

輸入樣例:1234567890987654321123456789

輸出樣例:yi san wu

#include<iostream>

using namespace std;

int main()

{

  char num[100]={0};

  int digit[100]={0};

  int sum=0;

  fgets(num,100,stdin);

  for(int i=0;num[i]!='\n';i++)

  {

    sum+=num[i];

  }

  for(int j=0;sum!=0;j++)

  {

    digit[j]=sum%10;

    sum/=10;

  }

  for(int k=j-1;k>=0;k--)

  {

    switch(digit[k]){

    case 0:
{
printf("ling");
break;
}
case 1:
{
printf("yi");
break;
}
case 2:
{
printf("er");
break;
}
case 3:
{
printf("san");
break;
}
case 4:
{
printf("si");
break;
}
case 5:
{
printf("wu");
break;
}
case 6:
{
printf("liu");
break;
}
case 7:
{
printf("qi");
break;
}
case 8:
{
printf("ba");
break;
}

case 9:
{
printf("jiu");
break;
}

    if(k!=0)

      cout<<" ";

   }

  return 0;

}

Tips:fgets函式功能為從指定的流中讀取資料,每次讀取一行。其原型為:char *fgets(char *str, int n, FILE *stream);從指定的流 stream 讀取一行,並把它儲存在 str 所指向的字串內。當讀取 (n-1) 個字元時,或者讀取到換行符時,或者到達檔案末尾時,它會停止。

姥姥的題解

#include<iostream>

#include<string>

using namespace std;

int main()

{

  string s;

  cin>>s;

  int sum=0;

  string str[10]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};

  for(int i=0;i<s.length();i++)

    sum+=(s[i]-'0');

  string num=to_string(sum);//將sum轉化為string型別的num

  for(int i=0;i<num.length();i++)

  {

    if(i!=0) cout<<" ";

    cout<<str[num[i]-'0'];

  }

  return 0;

}

Tips:用string接收輸入,string的每一位數字累加到sum裡面,再將sum轉化為string型別的num,對num的每一位輸出對應中文拼音。


【1003】我要通過

emmm目前還是沒敲出來,姥姥的題解也沒有完全理解,下次再寫

【1004】成績排名

讀入 n(>0)名學生的姓名、學號、成績,分別輸出成績最高和成績最低學生的姓名和學號。

輸入格式:

每個測試輸入包含 1 個測試用例,格式為

1 行:正整數 n
第 2 行:第 1 個學生的姓名 學號 成績
第 3 行:第 2 個學生的姓名 學號 成績
  ... ... ...
第 n+1 行:第 n 個學生的姓名 學號 成績

其中姓名學號均為不超過 10 個字元的字串,成績為 0 到 100 之間的一個整數,這裡保證在一組測試用例中沒有兩個學生的成績是相同的。

輸出格式:

對每個測試用例輸出 2 行,第 1 行是成績最高學生的姓名和學號,第 2 行是成績最低學生的姓名和學號,字串間有 1 空格。

輸入樣例:

3

Joe Math990112 89

Mike CS991301 100

Mary EE990830 95

輸出樣例:

Mike CS991301

Joe Math990112

#include<iostream>
using namespace std;
int main()
{
int count=0,score;
int max=-1,min=101;
string maxName,minName,maxNum,minNum,name,num;
cin>>count;
for(int i=0;i<count;i++)
{
cin>>name>>num>>score;
if(score>max)
{
max=score;
maxName=name;
maxNum=num;
}
if(score<min)
{
min=score;
minName=name;
minNum=num;
}
}
cout<<maxName<<' '<<maxNum<<endl;
cout<<minName<<' '<<minNum<<endl;
return 0;
}


【1005】繼續(3n+1)猜想

卡拉茲(Callatz)猜想已經在1001中給出了描述。在這個題目裡,情況稍微有些複雜。

當我們驗證卡拉茲猜想的時候,為了避免重複計算,可以記錄下遞推過程中遇到的每一個數。例如對 n=3 進行驗證的時候,我們需要計算 3、5、8、4、2、1,則當我們對 n=5、8、4、2 進行驗證的時候,就可以直接判定卡拉茲猜想的真偽,而不需要重複計算,因為這 4 個數已經在驗證3的時候遇到過了,我們稱 5、8、4、2 是被 3“覆蓋”的數。我們稱一個數列中的某個數 n 為“關鍵數”,如果 n 不能被數列中的其他數字所覆蓋。

現在給定一系列待驗證的數字,我們只需要驗證其中的幾個關鍵數,就可以不必再重複驗證餘下的數字。你的任務就是找出這些關鍵數字,並按從大到小的順序輸出它們。

輸入格式:

每個測試輸入包含 1 個測試用例,第 1 行給出一個正整數 K (<100),第 2 行給出 K 個互不相同的待驗證的正整數 n (1<n100)的值,數字間用空格隔開。

輸出格式:

每個測試用例的輸出佔一行,按從大到小的順序輸出關鍵數字。數字間用 1 個空格隔開,但一行中最後一個數字後沒有空格。

輸入樣例:

6

3 5 6 7 8 11

輸出樣例:

7 6

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int arr[10000];
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int count=0,n,flag=0;
cin>>count;
vector<int> v(count);
for(int i=0;i<count;i++)
{
cin>>n;
v[i]=n;
while(n!=1)
{
if(n%2)
n=3*n+1;
n/=2;
arr[n]=1;
}
}
sort(v.begin(),v.end(),cmp);//sort函式預設升序排序,用cmp函式實現降序排序
for(int i=0;i<count;i++)
{
if(arr[v[i]]==0)
{
if(flag==1)
cout<<" ";
cout<<v[i];
flag=1;
}
}
return 0;

}

Tips:sort函式預設升序排序,用cmp函式實現降序排序


【1006】換個格式輸出整數

讓我們用字母 B 來表示“百”、字母 S 表示“十”,用 12...n 來表示不為零的個位數字 n<10),換個格式來輸出任一個不超過 3 位的正整數。例如 234 應該被輸出為 BBSSS1234,因為它有 2 個“百”、3 個“十”、以及個位的 4。

輸入格式:

每個測試輸入包含 1 個測試用例,給出正整數 n(<1000)。

輸出格式:

每個測試用例的輸出佔一行,用規定的格式輸出 n。

輸入樣例 1:234

輸出樣例 1:BBSSS1234

輸入樣例 2:23

輸出樣例 2:SS123

#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int i,j,k,count;
i=n%10;
j=(n%100)/10;
k=n/100;
while(k--)
cout<<"B";
while(j--)
cout<<"S";
if(i)
{
for(int m=1;m<i+1;m++)
cout<<m;
}
return 0;
}


【1007】素數對猜想

d

輸入格式:

輸入在一行給出正整數N

輸出格式:

在一行中輸出不超過N的滿足猜想的素數對的個數。

輸入樣例:20

輸出樣例:4

#include<iostream>
using namespace std;
bool isPrime(int n)
{
for(int x=2;x*x<=n;x++)//必須要包含x*x=n的情況
if(n%x==0)
return false;
return true;
}
int main()
{
int n,count=0;
cin>>n;
for(int i=5;i<=n;i++)//別忘了n本身也可能是質數
if(isPrime(i)&&isPrime(i-2))
count++;
cout<<count;
return 0;
}


【1008】陣列元素迴圈右移問題

輸入格式:

每個輸入包含一個測試用例,第1行輸入N(1N100)和M(0);第2行輸入N個整數,之間用空格分隔。

輸出格式:

在一行中輸出迴圈右移M位以後的整數序列,之間用空格分隔,序列結尾不能有多餘空格。

輸入樣例:

6 2

1 2 3 4 5 6

輸出樣例:

5 6 1 2 3 4

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
m=m%n;
vector<int> arr(n);
for(int i=0;i<n;i++)
cin>>arr[i];
reverse(begin(arr),begin(arr)+n);//sort(arr.begin(),arr.end(),bmp);
reverse(begin(arr),begin(arr)+m);
reverse(begin(arr)+m,begin(arr)+n);
for(int j=0;j<n-1;j++)
cout<<arr[j]<<" ";
cout<<arr[n-1];
return 0;
}

Tips:sort(arr.begin(),arr.end(),bmp);

陣列長度為n,要想把陣列迴圈右移m位,只需要先將整個陣列a倒置,再將陣列前m位倒置,最後將陣列後n-m位倒置即可完成迴圈右移m位。

reverse()函式可以實現將一個數組或者vector中元素倒置,這個函式再algorithm標頭檔案中

如果m>n,那麼迴圈右移m位相當於迴圈右移m%n位,因為那些n倍數位的移動是多餘的,所以在使用m之前,先將m%n。


【1009】說反話

給定一句英語,要求你編寫程式,將句中所有單詞的順序顛倒輸出。

輸入格式:

測試輸入包含一個測試用例,在一行內給出總長度不超過 80 的字串。字串由若干單詞和若干空格組成,其中單詞是由英文字母(大小寫有區分)組成的字串,單詞之間用 1 個空格分開,輸入保證句子末尾沒有多餘的空格。

輸出格式:

每個測試用例的輸出佔一行,輸出倒序後的句子。

輸入樣例:Hello World Here I Come

輸出樣例:Come I Here World Hello

#include<iostream>
#include<stack>
using namespace std;
int main()
{
string s;
stack<string> st;
while(cin>>s)
st.push(s);
cout<<st.top();
st.pop();
while(!st.empty())
{
cout<<' '<<st.top();
st.pop();
}
return 0;
}


【1010】一元多項式求導

輸入格式:

以指數遞降方式輸入多項式非零項係數和指數(絕對值均為不超過 1000 的整數)。數字間以空格分隔。

輸出格式:

以與輸入相同的格式輸出導數多項式非零項的係數和指數。數字間以空格分隔,但結尾不能有多餘空格。注意“零多項式”的指數和係數都是 0,但是表示為 0 0

輸入樣例:3 4 -5 2 6 1 -2 0

輸出樣例:12 3 -10 1 6 0

#include<iostream>
using namespace std;
int main()
{
int a,b,flag=0;
while(cin>>a>>b)
{
if(b!=0)
{
if(flag==1)
cout<<" ";
cout<<a*b<<" "<<b-1;
flag=1;
}
}
if(flag==0)
cout<<"0 0";
return 0;
}算不超過#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
m=m%n;
vector<int> arr(n);
for(int i=0;i<n;i++)
cin>>arr[i];
reverse(begin(arr),begin(arr)+n);//sort(arr.begin(),arr.end(),bmp);
reverse(begin(arr),begin(arr)+m);
reverse(begin(arr)+m,begin(arr)+n);
for(int j=0;j<n-1;j++)
cout<<arr[j]<<" ";
cout<<arr[n-1];
return 0;N的滿足猜想的素​​),請計算不超過N的滿足猜想的素數對的個