PAT乙級(4)外星人的語言、選大王、 換個格式輸出整數 (water)
題目描述
nowcoder費了很大勁,終於和地外文明聯繫上。我們地球人通常有10根手指,因此我們習慣用10進制的數,而外星人的手指有16跟、8根等不等的數目,因此他們使用與我們不同的進制。爲了方便溝通,需要你開發一款工具,把地球人的10進制轉換成外星人的R進制形式。
輸入描述:
輸入有多行。每行包括兩個正整數n和R,其中2≤R≤16。輸入直到文件結束爲止。
輸出描述:
對於每個用例,輸出n對應的R進制形式。超過10進制的數,10用A表示、11用B表示,依次類推。
輸入例子:
1989 2
1119 16
輸出例子:
11111000101
45F
思路:
對於整數的進制轉換,就是將需要轉換的數 n 不斷去求餘 進制 r,記錄得到的數,然後 n = n /r 直到 n=0,
然後將求餘下來的數逆序輸出,可以存數組,也可以利用棧.
代碼:
C:
#include <iostream>
#include <stack>
using namespace std;
char trans[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
void fun(int n, int r)
{
int temp, ans = 0;
stack<int> s;
while (n!=0)
{
temp = n % r;
s.push(temp);
n = n / r;
}
while (!s.empty())
{
temp = s.top();
s.pop();
cout <<trans[temp];
}
cout <<endl;
}
int main()
{
long long n;
int r;
while (scanf_s("%d%d",&n,&r)!=EOF)
{
fun(n, r);
}
return 0;
}
Java :
//鏈接:https://www.nowcoder.com/questionTerminal/7848a03c2b744a94949166c2b49086ae
//只需一行Code即可秒殺!
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while(in.hasNext()){
System.out.println(Integer.toString(in.nextInt(), in.nextInt()).toUpperCase());
}
}
/*
public static String toString(int i, int radix)
將 i 轉換爲 radix 進制返回,最高支持 36進制
*/
題目描述
有n只猴子,按順時針方向圍成一圈選大王(編號從1到n),從第1號開始報數,一直數到m,數到m的猴子退出圈外,剩下的猴子再接着從 1 開始報數。就這樣,直到圈內只剩下一隻猴子時,這個猴子就是猴王。現在告訴你 n 和 m,請幫忙求出哪一隻猴子能當大王。
輸入描述:
輸入包含多組數據。每組數據包含兩個正整數 n 和m(1≤ m < n ≤ 10000)。
輸出描述:
對應每一組輸入,輸出猴王的編號 i(1≤i≤n)。
輸入例子:
7 3
8 3
輸出例子:
4
7
思路:
可以用頭尾相接的鏈表
也可以用數組,每次重置編號位置
最後是數學做法,約瑟夫問題:
無論是用鏈表實現還是用數組實現都有一個共同點:要模擬整個遊戲過程,不僅程序寫起來比較煩,而且時間複雜度高達O(nm),當n,m非常大(例如上百萬,上千萬)的時候,幾乎是沒有辦法在短時間內出結果的。我們注意到原問題僅僅是要求出最後的勝利者的序號,而不是要讀者模擬整個過程。因此如果要追求效率,就要打破常規,實施一點數學策略。
令f表示i個人玩遊戲報m退出最後勝利者的編號,最後的結果自然是f[n]
遞推公式
f[1]=0;
f[i]=(f[i-1]+m) mod i; (i>1)
有了這個公式,我們要做的就是從1-n順序算出f的數值,最後結果是f[n]。因爲實際生活中編號總是從1開始,我們輸出f[n]+1
由於是逐級遞推,不需要保存每個f,程序也是異常簡單:
(來自https://baike.baidu.com/item/%E7%BA%A6%E7%91%9F%E5%A4%AB%E9%97%AE%E9%A2%98/3857719?fr=aladdin)
代碼:
//約瑟夫問題 順序表最典型的應用
#include<stdio.h>
int main() {
int n, m;
while (scanf_s("%d %d", &n, &m) != EOF)
{
int r = 0, i;
for (i = 2; i <= n; i++)
r = (r + m) % i; //能用數學解決的就不要用算法
printf("%d\n", r + 1);
}
return 0;
}
題目描述
鏈接:https://www.nowcoder.com/questionTerminal/e56dbc5d5cf64587b25dc6b01ef71407來源:牛客網
讓我們用字母B來表示“百”、字母S表示“十”,用“12…n”來表示個位數字n(<10),換個格式來輸出任一個不超過3位的正整數。例如234
應該被輸出爲BBSSS1234,因爲它有2個“百”、3個“十”、以及個位的4。
輸入描述:
每個測試輸入包含1個測試用例,給出正整數n(<1000)。
輸出描述:
每個測試用例的輸出佔一行,用規定的格式輸出n。
輸入
234
輸出
BBSSS1234
代碼
#include <stdio.h>
int main()
{
int a;
int i =0 ;
int b =0 ;
int s =0;
int n = 0;
while(scanf("%d",&a) != EOF)
{
//b =a/100 ;
// a=a%100;
// s =a/10;
// n= a%10;
// n = a;
b = a/100;
s = a/10%10;
n = a%10;
for(i=0;i<b ;i++)
printf("B");
for(i=0;i<s ;i++)
printf("S");
for(i=1;i<=n;i++)
printf("%d",i);
}
return 0;
}
取各個位數的方法:
**b = a/100;**
**s = a/10%10;**
**n = a%10;**
進制轉換:
int temp, ans = 0;
stack s;
while (n!=0)
{
temp = n % r;
s.push(temp);
n = n / r;
}
while (!s.empty())
{
temp = s.top();
s.pop();
cout <<trans[temp];
}