1题目背景
从哪里跌倒就要从哪里爬起来!!!
上次给学弟学妹们出进制转换,居然没有一个人AC!于是这一次,心情绝望的学长决定出一回水水的进制转换作为这场考试的第一道水题。
(当然,也可能是唯一一道)
题目描述
作为迷你版进制转换,测试数据将给出一个十进制数据,你只需要编写程序输出这个十进制数据的二进制,八进制和十六进制表示。
注意:十六进制中10至15分别由A,B,C,D,E,F六个大写字母表示。
输入格式
一行,一个十进制正整数,为待转换的数字。
输出格式
三行,三个整数,分别为输入数据的二进制,八进制和十六进制表示。
样例一
input
27
output
11011
33
1B
限制与约定
对于100%的数据,输入的十进制数据在无符号的INT 范围内
递归解法
#include<cstdio>
#include<iostream>
using namespace std;
char MAP[6] = {'A', 'B', 'C', 'D', 'E', 'F'};
long long in;
void change(long long aim, long long sys){
if(aim){
change(aim/sys, sys);
int t = aim%sys;
if(t>=10) cout << MAP[t-10];
else cout << t;
}
}
int main(void){
// freopen("change10.in", "r", stdin);
// freopen("change10.out", "w", stdout);
cin >> in;
change(in, 2);
cout << endl;
change(in, 8);
cout << endl;
change(in, 16);
}
法三定义函数
#include<iostream>
using namespace std;
unsigned int num;
void zh(unsigned int num, int k){
int ws=0, d[40]={0};
while(num){
d[ws++]=num%k;
num/=k;
}
ws--;
for(int i=ws; i>=0; i--){
if(d[i]<=9) cout<<d[i];
if(d[i]==10) cout<<'A';
if(d[i]==11) cout<<'B';
if(d[i]==12) cout<<'C';
if(d[i]==13) cout<<'D';
if(d[i]==14) cout<<'E';
if(d[i]==15) cout<<'F';
}
cout<<endl;
}
int main(){
cin>>num;
zh(num, 2);
zh(num, 8);
zh(num, 16);
return 0;
}
函数解法
#include<iostream>
#include<cstdio>
using namespace std;
int a[50];
void f(long long n){
int m=0;
for(int j=1;j<=50;j++){
int d=0;
d=n%2;
if(n!=0) {a[j]=d;
m++;}
n/=2;}
for(int i=m;i>=1;i--)
cout<<a[i];
cout<<endl;
}
int main(){
long long n;
cin>>n;
f(n);
printf("%o\n",n);
printf("%X\n",n);
}
我的解法 比较长 忘了怎么定义函数 主要是忘了格式 汗!
#include<iostream>
#include<string>
using namespace std;
int s[1000010];
int main()
{
long long n;
cin>>n;
long long x,y,z;
for(int i=2;i<=16;i+=2)
{
if(i==2)
{
x=n;
long long c,m=0;
while(x!=0)
{
c=x%2;
x=x/2;
s[m]=c;
m++;
}
for(int i=m-1;i>=0;i--)
{
if(s[i]>=10) cout<<(char)(s[i]+55);
else cout<<s[i];
}
cout<<endl;
}
if(i==8)
{
y=n;
long long c,m=0;
while(y!=0)
{
c=y%8;
y=y/8;
s[m]=c;
m++;
}
for(int i=m-1;i>=0;i--)
{
if(s[i]>=10) cout<<(char)(s[i]+55);
else cout<<s[i];
}
cout<<endl;
}
if(i==16)
{
z=n;
long long c,m=0;
while(z!=0)
{
c=z%16;
z=z/16;
s[m]=c;
m++;
}
for(int i=m-1;i>=0;i--)
{
if(s[i]>=10) cout<<(char)(s[i]+55);
else cout<<s[i];
}
cout<<endl;
}
}
return 0;
}
2问题描述
众所周知,数学和OI是密切相关的,数学不仅是OI的基础,而且是算法的核心。因此,学习数论对于OIer们十分重要()。
在数论中,有一个叫做欧拉函数的东西,它的定义是这样的:对于正整数nn,欧拉函数是小于或等于nn的正整数中与nn互质的数的数目。我们特定1的欧拉函数值为1,即φ(1)=1φ(1)=1。(互质,若两个整数的最大公因数是1,则称这两个整数互质。)
现在我们设定一个概念,对于一个正整数nn,它满足φ(n)=n−1φ(n)=n−1,我们把这样的数称为AZe数。
现在AZe想问你,给出一个正整数mm,在闭区间[1,m][1,m]中,一共有多少个AZe数,区间内AZe数的极差是什么。(极差=最大值-最小值)
输入格式
一行一个正整数mm。
输出格式
一行两个正整数,用空格隔开,分别代表区间内AZe数的数量,极差。
样例
input
10
output
4 5
数据范围与约定
对于70%的数据,2≤m≤800002≤m≤80000。
对于100%的数据,2≤m≤100000002≤m≤10000000。
法1
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int P[10000010]={1,1};
int main(){
int ft,n,cnt=0;
int max=-1,min=20000000;
scanf("%d",&n);
for(int i=2;i<=ceil(sqrt(10000000));++i){
ft=0;
for(int j=2;j<=floor(sqrt(i));++j){
if(i%j==0){
ft=1;
break;
}
}
if(!ft){
for(int j=i*i;j<=10000000;j+=i){
P[j]=1;
}
}
}
for(int i=1;i<=n;++i){
if(!P[i]){
++cnt;
if(i>max) max=i;
if(i<min) min=i;
}
}
cout<<cnt<<" "<<max-min;
return 0;
}
法二 kb的解法
#include<iostream>
#include<cmath>
using namespace std;
bool a[10000010]{1, 1};
int main(){
for(int i=2; i<=ceil(sqrt(10000005)); i++){
int flag=1;
for(int j=2; j<=floor(sqrt(i)); j++){
if(i%j==0){
flag=0;
a[i]=1;
break;
}
}
if(flag)
for(int j=i*i; j<=10000005; j+=i)
a[j]=1;
}
int n, cnt=0, tmax=-1, tmin=100000;
cin>>n;
for(int i=1; i<=n; i++){
if(a[i]==0){
if(i>tmax)
tmax=i;
if(i<tmin)
tmin=i;
cnt++;
}
}
cout<<cnt<<" "<<tmax-tmin;
return 0;
}
法三
#include<iostream>
using namespace std;
bool is[10000000]={0};
int zhishu[10000000];
int main(){
int n,cnt=0,max=-1,min=100000000;
cin>>n;
for(int i=2;i<=n;i++)
is[i]=true;
for(int i=2;i<=n;i++){
if(is[i]){
zhishu[++cnt]=i;
for(int j=i*2;j<=n;j+=i)
is[j]=false;}
}
for(int i=1;i<=cnt;i++){
max=zhishu[i]>max?zhishu[i]:max;
min=zhishu[i]<min?zhishu[i]:min;}
cout<<cnt<<" "<<max-min;
return 0;
}
法4
#include<iostream>
using namespace std;
const int inf=10000005;
int prime[inf];
bool is_prime[inf+1];
int shai(int n){
int p=0;
for(int i=0;i<=n;i++) is_prime[i]=true;
is_prime[0]=false;
is_prime[1]=false;
for(int i=2; i<=n; i++){
if(is_prime[i]){
prime[p++]=i;
for(int j=2; j*i<=n; j++)
is_prime[j*i]=false;
}
}
return p;
}
int main(){
int m;
cin>>m;
int num=shai(m);
cout<<num<<" "<<prime[num-1]-2;
return 0;
}
3双月同天
问题背景
双月同天,天机无限。且看今夜,时空错现。
今夜 LFYZ 的天空,闪过一个神秘的像素矩阵。有人认为它是恶毒的巫术,有人则把它视作灵魂信仰。
0xis 解码后,发现这是一段 A++ 代码。来回翻阅代码十分麻烦,吊打高二的你决定帮助 0xis。
问题描述
A++ 的变量前需要加
int=5;
int+1;。A++ 的变量不需要定义,直接给变量赋值即可。
只有字母才是 A++ 变量的合法标识符,数字和下划线不是,其他的更不是。
阅读代码很快就使 0xis 眼花缭乱,他忘记一个变量在何处出现了。请帮助他得出变量首次出现的位置和变量出现的次数。
重要的事情说三遍:
• 保证不会在” “、注释等内出现
字符都表示变量。
• 保证不会在” “、注释等内出现
字符都表示变量。
• 保证不会在” “、注释等内出现
字符都表示变量。
输入格式
第一行一个字串,代表接收到的 A++ 源码。源码不含空格和回车。
第二行一个字串,代表 0xis 找不到的变量。输入时不包含
前面(不含
a=3;
a+
akioi=3;echo(“this_problem_defends_ak”);
ak
output
-1
数据范围与约定
对于 30% 的数据,保证是常见数据结构和算法的 A++ 实现。
对于 100% 的数据,两个字串长度均在 10000 之内。
再强调一遍:保证不会在” “、注释等内出现
字符都表示变量。
时间限制: 1s1s
内存限制: 128MB128MB
题目来源:
C++ 语言基础测试
naci的解法
#include <cstdio>
#include <cstring>
#include <cctype>
#include <iostream>
const int MAXN = 1000001;
char a[MAXN], b[MAXN] = "$"; int f[MAXN] = {-1},
ans = 0, fir = -1;
int main() {
std::cin >> a >> b + 1;
int la = strlen(a), lb = strlen(b);
for(int i = 0, j = 1;; i++, j++)
if(j >= lb) { f[j] = i; break; }
else if(b[i] == b[j]) f[j] = f[i];
else { f[j] = i; do i = f[i]; while(i >= 0 && b[i] != b[j]); }
for(int i = 0, j = 0; i < la; )
if(a[i] == b[j]) { i++, j++; if(j == lb) { j = f[j];
if(!isalpha(a[i])) { ans++; if(!~fir) fir = i - lb; }}}
else { j = f[j]; if(j < 0) i++, j++; }
std::cout << fir << ' ' << ans << std::endl;
return 0;
}
cyx的解法
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[10100];
char a[10100];
int lena;
int cnt=0;
bool ft=1;
int main () {
cin.getline(s,10000);
cin.getline(a,10000);
int lens=strlen(s);
int lena=strlen(a);
for(int i=0; i<lens; ++i) {
if(s[i]=='$') {
bool f=0;
++i;
int lenc=0;
//读取长度
while(s[i]>='a' && s[i]<='z') {
++lenc;
++i;
}
--i;
//比较长度
if(lenc==lena) {
//判断相同
for(int j=lena-1,z=i; j>=0; j--,z--) {
if(a[j]!=s[z]) {
f=1;
break;
}
}
} else {
continue;
}
//判断
if(!f ) {
if(ft) {
cout<<i-lenc;
ft=0;
}
++cnt;//计数
}
}
}
if(ft) {
cout<<"-1";
}else{
cout<<" "<<cnt;
}
return 0;
}
kb的解法
#include<iostream>
#include<cstring>
using namespace std;
char a[10010];
char b[10010];
int main(){
cin>>a;
cin>>b;
int flag=1, wz, cnt=0;
for(int i=0; i<strlen(a); i++){
int ws=-1;
if(a[i]=='$'){
char c[10010]={'0'};
for(int j=i+1; ; j++){
if(a[j]>'z' || a[j]<'a')
break;
c[++ws]=a[j];
}
if(strstr(c, b)){
if(strstr(b, c)){
cnt++;
if(flag){
wz=i;
flag=0;
}
}
}
}
}
if(cnt!=0)
cout<<wz<<" "<<cnt;
else
cout<<"-1";
return 0;
}
4问题背景
巴瓦鲁魔法图书馆里的图书已经好久没整理了,管理者帕秋莉•诺蕾姬(PatchouliKnowledgePatchouliKnowledge)决定把它们分类整理,类别的个数是一定的,而她想知道这些书分类的方案有多少种,于是来请教你。
问题描述
把 MM 本书(书都视为一样的)分成 NN 类,不允许有的种类为空,即每种至少有一本书,问共有多少种不同的分法。
P.S.P.S. 像8,3,38,3,3 和 3,3,83,3,8 是同一种分法。
P.S.P.S. 像6,0,06,0,0 和 0,0,60,0,6 是不正确的分法。
输入格式
输入只有一行,即 MM 与 NN (保证 M>NM>N )。
输出格式
一个数,即为分类方案的个数。
样例一
input
8 5
output
3
样例二
input
16 9
output
15
数据范围与约定
对于 100% 的数据,M<=150M<=150, N<=10N<=10,MM 与 NN 都为正数。
时间限制: 1s1s
内存限制: 256MB256MB
提示
这是一道用递归的题,
总方案数=全部类别中没有只有一本书的方案数+只有一个类别有一本书(其他类别的书都大于1)的方案数,
假设允许有的种类里没有书,设all(m,n)为把 MM 本书(书都视为一样的)分成 NN 类的种数,即:
all(m,n)=all(m-n,n)+all(m,n-1);
请注意递归边界。
请注意递归边界。
请注意递归边界。
当然,会用动态规划更好。
题目来源:
C++ 语言基础测试
kb的解法
#include<iostream>
using namespace std;
int all(int m, int n){
if(m<n) return 0;
if(m==n) return 1;
if(n==1) return 1;
else return all(m-n, n)+all(m-1, n-1);
}
int main(){
int m, n;
cin>>m>>n;
cout<<all(m, n);
return 0;
}
5问题背景
老韩让书名号出一道普通题,于是他出了nn道题(1−n)(1−n),让鱼人们去做,并让它们给出每道题的普通指数aiai,你能帮帮书名号,帮他把题目按照普通度排序么? 与上次不同的是,如果普通指数相同,你需要按照编号从大到小排列。
输入格式
第一行一个整数nn,代表题目的数量。 第二行nn个数字,代表每道题的普通指数。
输出格式
一行nn个数,代表排序好的题目编号(请不要在末尾留空格)
样例一
input
5
1 2 3 3 4
output
1 2 4 3 5
数据范围与约定
对于 10%的数据,普通指数不存在重复。 对于 20%的数据,n<=1000n<=1000。 对于 70%的数据,n<=10000n<=10000。 对于 100% 的数据,ai<=10000ai<=10000, n<=200000n<=200000,aiai 与 nn 都为正数。
时间限制: 1s1s
内存限制: 256MB256MB
提示
这是一道双关键字排序题,用桶其实也可以
题目来源:
C++ 语言基础测试
时间264ms
#include<iostream>
#include<algorithm>
using namespace std;
struct item{
int ai, no;
};
bool cmp(item a, item b){
if(a.ai<b.ai) return true;
if(a.ai>b.ai) return false;
if(a.ai==b.ai){
if(a.no<b.no) return false;
else return true;
}
}
int n;
item d[200010];
int main(){
cin>>n;
for(int i=1; i<=n; i++){
cin>>d[i].ai;
d[i].no=i;
}
sort(d+1, d+n+1, cmp);
for(int i=1; i<n; i++)
cout<<d[i].no<<" ";
cout<<d[n].no<<endl;
return 0;
}
时间164ms
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct item{
int ai, no;
};
bool cmp(item a, item b){
if(a.ai<b.ai) return true;
if(a.ai>b.ai) return false;
if(a.ai==b.ai){
if(a.no<b.no) return false;
else return true;
}
}
int n;
item d[200010];
int main(){
scanf("%d", &n);
for(int i=1; i<=n; i++){
scanf("%d", &d[i].ai);
d[i].no=i;
}
sort(d+1, d+n+1, cmp);
for(int i=1; i<n; i++)
printf("%d ", d[i].no);
printf("%d\n", d[n].no);
return 0;
}
这两段代码充分的证明了cin及scanf的效率。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct number
{
int xh;
int point;
}a[200005];
bool cmp(number x,number y)
{
if(x.point==y.point) return x.xh>y.xh;
else return x.point<y.point;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i].point),a[i].xh=i;
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++) printf("%d ",a[i].xh);
return 0;
}
SocietyNiu的解法
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct number
{
int xh;
int point;
}a[200005];
bool cmp(number x,number y)
{
if(x.point==y.point) return x.xh>y.xh;
else return x.point<y.point;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i].point),a[i].xh=i;
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++) printf("%d ",a[i].xh);
return 0;
}