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];
}