目录
2.A + B for Matrices(浙江大学复试上机题)
9、数学问题
1)进制转换
1.二进制数(北京邮电大学复试上机题)
题目描述:
大家都知道,数据在计算机中是以二进制形式存储的。有一天,小明在学习C 语言时,想知道一个类型为 unsigned int 的数字存储在计算机中的二进制串是什么样子的。你能帮帮小明吗?注意,小明不想要二进制串中前面没有意义的 0 串,即要去掉前导 0。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
stack<int> s;
cin>>n;
while(n != 0){
s.push(n%2);
n /= 2;
}
while(!s.empty()) {
cout<<s.top();
s.pop();
}
return 0;
}
2.进制转换(清华大学复试上机题)
题目描述:
将一个长度最多为 30 位数字的十进制非负整数转换为二进制数。
#include <bits/stdc++.h>
using namespace std;
string str;
void divide(){
int remain=0; //保留余数
for(int i=0;i<str.size();++i){
int t = remain * 10 + str[i] - '0';
remain = t % 2;
str[i] = t / 2 + '0';
}
while(str[0]=='0'){ //对于字符串除***有得到的商最前面有0,必须把0删除
str.erase(0,1);
}
}
int main(){
while(getline(cin,str)){
stack<int> s;
while(str.size() > 0){
s.push((str[str.size() - 1] - '0') % 2);
divide();
}
while(!s.empty()){
cout<<s.top();
s.pop();
}
cout<<endl;
}
return 0;
}
3.十进制与二进制(清华大学复试上机题)
题目描述:
对于一个十进制数 A,将 A 转换为二进制数,然后按位逆序排列,再转换为十进制数B,B即为A 的二进制逆序数。例如,对于十进制数 173,其二进制形式为 10101101,逆序排列得到10110101,其十进制数为 181,181 即为 173 的二进制逆序数。
#include <bits/stdc++.h>
using namespace std;
string Divide(string str, int x){
int remainder = 0;
for(int i = 0;i < str.size();i++){
int current = remainder * 10 + str[i] - '0';
str[i] = current / x + '0';
remainder = current % x;
}
int pos = 0;
while(str[pos] == '0') pos++;
return str.substr(pos);
}
string Multiple(string str,int x){
int carry = 0;
for(int i = str.size() - 1;i >= 0;--i){
int current = x * (str[i] - '0') + carry;
str[i] = current % 10 + '0';
carry = current / 10;
}
if(carry != 0) str = "1" + str;
return str;
}
string Add(string str,int x){
int carry = x;
for(int i = str.size() - 1;i >= 0;--i){
int current = (str[i] - '0') + carry;
str[i] = current % 10 + '0';
carry = current / 10;
}
if(carry != 0) str = "1" + str;
return str;
}
int main(){
string str;
while(cin>>str){
vector<int> binary;
while(str.size() != 0){
int last = str[str.size() - 1] - '0';
binary.push_back(last % 2);
str = Divide(str, 2);
}
string answer = "0";
for(int i = 0;i < binary.size();i++){
answer = Multiple(answer,2);
answer = Add(answer,binary[i]);
}
cout<<answer<<endl;
}
return 0;
}
4.进制转换 2(清华大学复试上机题)
题目描述:
将 M 进制的数 X 转换为 N 进制的数并输出。
#include <bits/stdc++.h>
using namespace std;
//数字转字符
char intToChar(int x){
if(x < 10) return x + '0';
else return x - 10 + 'a';
}
//字符转数字
int charToInt(char c){
if(c >= '0' && c <= '9') return c - '0';
else return c - 'A' + 10;
}
int main(){
int M,N;
cin>>M>>N;
string str;
cin>>str;
long long number = 0;
for(int i = 0;i < str.size();i++){
number *= M;
number += charToInt(str[i]);
}
vector<char> answer;
while(number != 0){
answer.push_back(intToChar(number % N));
number /= N;
}
for(int i = answer.size() - 1;i >= 0;--i){
cout<<answer[i];
}
cout<<endl;
return 0;
}
5.八进制(华中科技大学复试上机题)
题目描述:
输入一个整数,将其转换成八进制数并输出。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
stack<int> s;
while(cin>>n){
if(n == 0){
cout<<0<<endl;
return 0;
}
int answer = 0;
while(n != 0){
s.push(n%8);
n /= 8;
}
while(!s.empty()){
cout<<s.top();
s.pop();
}
cout<<endl;
}
return 0;
}
6.又一版 A + B(浙江大学复试上机题)
题目描述:
输入两个不超过整型定义的非负十进制整数 A 和 B(<= 231-1),输出 A + B 的m(1 < m< 10)进制数。
#include <bits/stdc++.h>
using namespace std;
int main(){
int m,a,b;
long long answer;
stack<int> s;
while(cin>>m){
if(m == 0) break;
cin>>a>>b;
answer = a + b;
if(answer == 0) {
cout<<0<<endl;
continue;
}
while(answer != 0){
s.push(answer % m);
answer /= m;
}
while(!s.empty()){
cout<<s.top();
s.pop();
}
cout<<endl;
}
return 0;
}
7.进制转换(北京大学复试上机题)
题目描述:
写出一个程序,接受一个十六进制的数值字符串,输出该数值的十进制字符串(注意可能存在的一个测试用例里的多组数据)。
#include <bits/stdc++.h>
using namespace std;
int main(){
string str;
while(getline(cin,str)){
int answer = 0;
for(int i = 2;i < str.size();i++){
if(str[i] <= '9'){
answer = answer * 16 + str[i] - '0';
}else{
answer = answer * 16 + str[i] - 'A' + 10;
}
}
cout<<answer<<endl;
}
return 0;
}
2)最大公约数与最小公倍数
1.最大公约数(哈尔滨工业大学复试上机题)
题目描述:
输入两个正整数,求其最大公约数。
#include <bits/stdc++.h>
using namespace std;
//最大公约数
long long gcd(long long a,long long b){
if(b == 0) return a;
return gcd(b,a%b);
}
//最小公倍数
long long lcm(long long a,long long b){
return a * b / gcd(a,b);
}
int main(){
long long a,b;
cin>>a>>b;
cout<<gcd(a,b)<<endl;
return 0;
}
2.最小公倍数
题目描述:
给定两个正整数,计算这两个数的最小公倍数。
#include <bits/stdc++.h>
using namespace std;
//最大公约数
long long gcd(long long a,long long b){
if(b == 0) return a;
return gcd(b,a%b);
}
//最小公倍数
long long lcm(long long a,long long b){
return a * b / gcd(a,b);
}
int main(){
long long a,b;
cin>>a>>b;
cout<<lcm(a,b)<<endl;
return 0;
}
3.最简真分数(北京大学复试上机题)
题目描述:
给出 n 个正整数,任取两个数分别作为分子和分母组成最简真分数,编程求共有几个这样的组合。
#include <bits/stdc++.h>
using namespace std;
//最大公约数
long long gcd(long long a,long long b){
if(b == 0) return a;
return gcd(b,a%b);
}
//最小公倍数
long long lcm(long long a,long long b){
return a * b / gcd(a,b);
}
int main(){
int n;
int arr[600];
int answer = 0;
while(cin>>n){
if(n == 0) break;
answer = 0;
for(int i = 0;i < n;i++)
cin>>arr[i];
for(int i = 0;i < n;i++){
for(int j = i+1;j < n;j++){
if(gcd(arr[i],arr[j]) == 1) answer++;
}
}
cout<<answer<<endl;
}
return 0;
}
3)质数
1.素数判定(哈尔滨工业大学复试上机题)
题目描述:
给定一个数 n,要求判断其是否为素数(0, 1 和负数都是非素数)。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,flag = 1;
cin>>n;
if(n == 1) {
cout<<"no"<<endl;
return 0;
}
for(int i = 2;i < n;i++)
if(n % i == 0) flag = 0;
if(flag == 0) cout<<"no"<<endl;
else cout<<"yes"<<endl;
return 0;
}
2.素数(北京航空航天大学复试上机题)
题目描述:
输入一个整数 n(2 <= n <= 10000),要求输出所有从 1 到这个整数之间(不包括1 和这个整数)个位为 1 的素数,若没有则输出-1。
#include <bits/stdc++.h>
using namespace std;
bool judge(int n){
for(int i = 2;i < n;i++)
if(n % i == 0) return false;
return true;
}
int main(){
int n;
cin>>n;
for(int i = 2;i < n;i++)
if(judge(i) && i % 10 == 1) cout<<i<<" ";
return 0;
}
3.Prime Number(上海交通大学复试上机题)
题目描述:
输出第 k 个质数。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 150000;
bool isPrime[MAXN];
vector<int> Prime;
void Select(){
for(int i = 0;i < MAXN;i++){
isPrime[i] = true;
}
isPrime[0] = isPrime[1] = false;
for(int i = 2;i < MAXN;i++){
if(isPrime[i]){
Prime.push_back(i);
//过滤
for(int j = i * i;j < MAXN;j += i){
isPrime[j] = false;
}
}
}
}
int main(){
int n;
Select();
while(cin>>n){
cout<<Prime[n-1]<<endl;
}
return 0;
}
4)分解质因数
1.质因数的个数(清华大学复试上机题)
题目描述:
求正整数 N(N > 1)的质因数的个数。相同的质因数需要重复计算。例如,120 = 2*2*2*3*5,共有 5 个质因数。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100000;
bool isPrime[MAXN];
vector<int> Prime;
void Select(){
for(int i = 0;i < MAXN;i++){
isPrime[i] = true;
}
isPrime[0] = isPrime[1] = false;
for(int i = 2;i < MAXN;i++){
if(isPrime[i]){
Prime.push_back(i);
for(int j = i * i;j < MAXN;j += i){
isPrime[j] = false;
}
}
}
}
int main(){
int n;
Select();
while(cin>>n){
int cnt = 0;
for(int i = 0;i < Prime.size() && Prime[i] < n;i++){
int factor = Prime[i];
while(n % factor == 0){
n /= factor;
cnt++;
}
}
if(n > 1) cnt++;
cout<<cnt<<endl;
}
return 0;
}
2.约数的个数(清华大学复试上机题)
题目描述:
输入 n 个整数,依次输出每个数的约数的个数。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,t;
while(cin>>n){
for(int i = 0;i < n;i++){
cin>>t;
int cnt = 0;
int s = sqrt(t);
for(int j = 1;j * j < t;j++){
if(t % j == 0) cnt += 2;
}
if(s * s == t) cnt++;
cout<<cnt<<endl;
}
}
return 0;
}
5)快速幂
1.人见人爱 A^B
题目描述:
求 A^B 的最后三位数表示的整数。说明:A^B 的含义是“A 的 B 次方”。
#include <bits/stdc++.h>
using namespace std;
//a^b
int fast(int a,int b,int mod){
int answer = 1;
//不断将b转换为二进制
while(b != 0){
//累计乘a的2^k次幂
if(b % 2 == 1){
answer *= a;
answer %= mod;
}
b /= 2;
//不断平方
a *= a;
a %= mod;
}
return answer;
}
int main(){
int a,b;
while(cin>>a>>b){
if(a == 0 && b == 0) break;
cout<<fast(a,b,1000)<<endl;
}
return 0;
}
6)矩阵与矩阵快速幂
1.计算两个矩阵的乘积(哈尔滨工业大学复试上机题)
题目描述:
计算两个矩阵的乘积,第一个是 2*3,第二个是 3*2。
#include <bits/stdc++.h>
using namespace std;
int main(){
int a[2][3];
int b[3][2];
int c[3][3];
for(int i = 0;i < 2;i++)
for(int j = 0;j < 3;j++)
cin>>a[i][j];
for(int i = 0;i < 3;i++)
for(int j = 0;j < 2;j++)
cin>>b[i][j];
for(int i = 0;i < 3;i++)
for(int j = 0;j < 3;j++){
c[i][j] = 0;
for(int k = 0;k < 3;k++){
c[i][j] += a[i][k] * b[k][j];
}
}
for(int i = 0;i < 2;i++){
for(int j = 0;j < 2;j++){
cout<<c[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
2.A + B for Matrices(浙江大学复试上机题)
题目描述:
计算 A + B,其中 A 和 B 是两个矩阵,然后统计矩阵中全为零的行和列的数目。
#include <bits/stdc++.h>
using namespace std;
int main(){
int arr[10][10];
int row,col;
while(cin>>row>>col){
for(int i = 0;i < row;i++){
for(int j = 0;j < col;j++){
cin>>arr[i][j];
}
}
int t;
for(int i = 0;i < row;i++){
for(int j = 0;j < col;j++){
cin>>t;
arr[i][j] += t;
}
}
int cnt = 0;
//每一行
for(int i = 0;i < row;i++){
int flag = 1;
for(int j = 0;j < col;j++){
if(arr[i][j] != 0) {
flag = 0;
break;
}
}
if(flag) cnt++;
}
//每一列
for(int i = 0;i < col;i++){
int flag = 1;
for(int j = 0;j < row;j++){
if(arr[j][i] != 0) {
flag = 0;
break;
}
}
if(flag) cnt++;
}
cout<<cnt<<endl;
}
return 0;
}
10、贪心
1)简单贪心
1.鸡兔同笼(北京大学复试上机题)
题目描述:
一个笼子里面关了鸡和兔子(鸡有 2 只脚,兔子有 4 只脚,没有例外)。已知笼子里面脚的总数是 a,问笼子里面至少有多少只动物,至多有多少只动物。
#include <bits/stdc++.h>
using namespace std;
int main(){
int a;
while(cin>>a){
int minN = 0;
int maxN = 0;
if(a % 2 == 0){
minN = a / 4 + (a % 4) / 2;
maxN = a / 2;
cout<<minN<<" "<<maxN<<endl;
}else
cout<<0<<" "<<0<<endl;
}
return 0;
}
2)区间贪心
1.今年暑假不 AC
题目描述:
“今年暑假不 AC?” “是的。” “那你干什么呢?” “看世界杯呀,笨蛋!” 确实如此,世界杯来了,球迷的节日也来了,估计很多 ACMer 也会抛开计算机,奔向电视了。作为球迷,一定想看尽量多的完整的比赛。当然,作为新时代的好青年,你一定还会看一些其他的节目,如《新闻联播》(永远不要忘记关心国家大事)《非常 6+7》《超级女声》及王小丫主持的《开心辞典》等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目。)
#include <bits/stdc++.h>
using namespace std;
struct program{
int start;
int end;
}p[100];
bool cmp(program p1,program p2){
return p1.end < p2.end;
}
int main(){
int n;
while(cin>>n){
if(n == 0) break;
for(int i = 0;i < n;i++){
cin>>p[i].start>>p[i].end;
}
//结束时间升序排序
sort(p,p+n,cmp);
int cnt = 0;
int current = 0;
for(int i = 0;i < n;i++){
if(current <= p[i].start){
current = p[i].end;
cnt++;
}
}
cout<<cnt<<endl;
}
return 0;
}