时间限制:1.0s 内存限制:256.0MB
问题描述
Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。
当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。
输入格式
输入包含一个整数n。
输出格式
输出一行,包含一个整数,表示Fn除以10007的余数。
说明:在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以10007取余数,直接计算余数往往比先算出原数再取余简单。
样例输入
10
样例输出
55
样例输入
22
样例输出
7704
数据规模与约定
1 <= n <= 1,000,000。
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int s;
int arr[10008];
int main()
{
int i,n,a,b,t;
arr[1]=1;
arr[2]=1;
for(i=3;i<=10007;i++)
{
arr[i]=(arr[i-1]+arr[i-2])%10007;
}
while(scanf("%d",&n)==1)
{
if(n>10007)
{
a=arr[10006];
b=arr[10007];
for(i=10008;i<=n;i++)
{
t=b;
b=(a+b)%10007;
a=t;
}
}
else
{
b=arr[n];
}
printf("%d\n",b);
}
return 0;
}
01字串
时间限制:1.0s 内存限制:256.0MB
问题描述
对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:
00000
00001
00010
00011
00100
请按从小到大的顺序输出这32种01串。
输入格式
本试题没有输入。
输出格式
输出32行,按从小到大的顺序每行一个长度为5的01串。
样例输出
00000
00001
00010
00011
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
int n,m,i,j,k,t;
int a[6];
for(i=0;i<32;i++)
{
memset(a,0,sizeof(a));
j=1;
t=i;
while(t!=0)
{
a[j]=(1&t);
t>>=1;
j++;
}
for(k=5;k>=1;k--)
printf("%d",a[k]);
printf("\n");
}
return 0;
}
算法训练 Anagrams问题
时间限制:1.0s 内存限制:512.0MB
问题描述
Anagrams指的是具有如下特性的两个单词:在这两个单词当中,每一个英文字母(不区分大小写)所出现的次数都是相同的。例如,“Unclear”和“Nuclear”、“Rimon”和“MinOR”都是Anagrams。编写一个程序,输入两个单词,然后判断一下,这两个单词是否是Anagrams。每一个单词的长度不会超过80个字符,而且是大小写无关的。
输入格式:输入有两行,分别为两个单词。
输出格式:输出只有一个字母Y或N,分别表示Yes和No。
输入输出样例
样例输入
Unclear
Nuclear
样例输出
Y
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
string train(string &s1)//格式化
{
string ss1=s1;
for(int i=0;i<s1.length();i++)
{
ss1[i]=tolower(s1[i]);
}
sort(ss1.begin(),ss1.end());
return ss1;
}
int main()
{
string s1,s2;
while(cin>>s1>>s2)
{
if(s1.length()!=s2.length())
printf("N\n");
else
{
string r1=train(s1);
string r2=train(s2);
cout<<r1<<endl<<r2<<endl;
if(r1==r2)
{
printf("Y\n");
}
else
printf("N\n");
}
}
return 0;
}
十六进制转十进制
时间限制:1.0s 内存限制:512.0MB
问题描述
从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出。
注:十六进制数中的10~15分别用大写的英文字母A、B、C、D、E、F表示。
样例输入
FFFF
样例输出
65535
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
int main()
{
int i;
long long s;
int a[6]={10,11,12,13,14,15};
string t;
while(cin>>t)
{
s=0;
for(i=0;i<t.length();i++)
{
if(t[i]-'0'>=0&&t[i]-'0'<=9)
{
s=s*16+(t[i]-'0');
}
else
{
s=s*16+a[t[i]-'A'];
}
}
printf("%I64d\n",s);
}
return 0;
}
基础练习 十进制转十六进制
时间限制:1.0s 内存限制:512.0MB
问题描述
十六进制数是在程序设计时经常要使用到的一种整数的表示方式。它有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F共16个符号,分别表示十进制数的0至15。十六进制的计数方法是满16进1,所以十进制数16在十六进制中是10,而十进制的17在十六进制中是11,以此类推,十进制的30在十六进制中是1E。
给出一个非负整数,将它表示成十六进制的形式。
输入格式
输入包含一个非负整数a,表示要转换的数。0<=a<=2147483647
输出格式
输出这个整数的16进制表示
样例输入
30
样例输出
1E
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
using namespace std;
char a[17]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
int main()
{
long long n,m;
int cnt,i;
while(scanf("%I64d",&n)!=EOF)
{
if(n==0)
{
printf("0\n");
continue;
}
string ans;
ans="";
while(n!=0)
{
m=n%16;
ans+=a[m];
n/=16;
}
for(i=ans.length()-1;i>=0;i--)
printf("%c",ans[i]);
printf("\n");
}
return 0;
}
基础练习 十六进制转八进制
时间限制:1.0s 内存限制:512.0MB
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
注意
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
提示
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
解法1:
#include <iostream>
#include <cstdio>
#include <string>
#include <map>
using namespace std;
map<char, string> hex_to_bin;
map<string, char> bin_to_oct;
map<char, string> hex_to_oct;
void init() {
hex_to_bin['0'] = "0000"; hex_to_bin['1'] = "0001";
hex_to_bin['2'] = "0010"; hex_to_bin['3'] = "0011";
hex_to_bin['4'] = "0100"; hex_to_bin['5'] = "0101";
hex_to_bin['6'] = "0110"; hex_to_bin['7'] = "0111";
hex_to_bin['8'] = "1000"; hex_to_bin['9'] = "1001";
hex_to_bin['A'] = "1010"; hex_to_bin['B'] = "1011";
hex_to_bin['C'] = "1100"; hex_to_bin['D'] = "1101";
hex_to_bin['E'] = "1110"; hex_to_bin['F'] = "1111";
bin_to_oct["000"] = '0'; bin_to_oct["001"] = '1';
bin_to_oct["010"] = '2'; bin_to_oct["011"] = '3';
bin_to_oct["100"] = '4'; bin_to_oct["101"] = '5';
bin_to_oct["110"] = '6'; bin_to_oct["111"] = '7';
hex_to_oct['0'] = "0"; hex_to_oct['1'] = "1";
hex_to_oct['2'] = "2"; hex_to_oct['3'] = "3";
hex_to_oct['4'] = "4"; hex_to_oct['5'] = "5";
hex_to_oct['6'] = "6"; hex_to_oct['7'] = "7";
hex_to_oct['8'] = "10"; hex_to_oct['9'] = "11";
hex_to_oct['A'] = "12"; hex_to_oct['B'] = "13";
hex_to_oct['C'] = "14"; hex_to_oct['D'] = "15";
hex_to_oct['E'] = "16"; hex_to_oct['F'] = "17";
}
int main()
{
init();
int n;
scanf("%d", &n);
while (n--) {
string s;
cin >> s;
string bin;
for (int i = 0; i < s.size(); ++i)
bin += hex_to_bin[s[i]];
if (s == "0") {
cout << "0" << endl;
continue;
}
if (bin.size() % 3 == 1)
bin = "00" + bin;
if (bin.size() % 3 == 2)
bin = "0" + bin;
string ans;
for (int i = 0; i < bin.size(); i += 3)
ans += bin_to_oct[bin.substr(i, 3)];
int ind = 0;
while (ans[ind] == '0')
++ind;
for ( ; ind < ans.size(); ++ind)
cout << ans[ind];
cout << endl;
}
return 0;
}
解法2:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <set>
using namespace std;
char str[100005], num;
void Fun(int i, int state)
{
int temp;
if(i < 0)
{
if(num != 0)
{
printf("%d", num);
}
return;
}
if(state != 3)
{
temp = str[i] >= '0' && str[i] <= '9' ? str[i] - '0' : str[i] - 'A' + 10;
temp <<= state;
num |= temp;
temp = num;
num >>= 3;
Fun(i - 1, state + 1);
printf("%d", (temp & 1) + (temp & 2) + (temp & 4));
}
else
{
temp = num;
num >>= 3;
Fun(i, 0);
printf("%d", (temp & 1) + (temp & 2) + (temp & 4));
}
}
int main()
{
int n;
scanf("%d", &n);
while(n--)
{
num = 0;
scanf("%s", str);
Fun(strlen(str) - 1, 0);
printf("\n");
}
return 0;
}
算法训练 出现次数最多的整数
时间限制:1.0s 内存限制:512.0MB
问题描述
编写一个程序,读入一组整数,这组整数是按照从小到大的顺序排列的,它们的个数N也是由用户输入的,最多不会超过20。然后程序将对这个数组进行统计,把出现次数最多的那个数组元素值打印出来。如果有两个元素值出现的次数相同,即并列第一,那么只打印比较小的那个值。
输入格式:第一行是一个整数N,N £ 20;接下来有N行,每一行表示一个整数,并且按照从小到大的顺序排列。
输出格式:输出只有一行,即出现次数最多的那个元素值。
输入输出样例
样例输入
5
100
150
150
200
250
样例输出
150
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
using namespace std;
int a[22],b[22];
int main()
{
int maxn,ans,n,t,cnt,i,j;
while(scanf("%d",&n)!=EOF)
{
if(n<=0)//注意特判!!!否则是错的!!!
continue;
memset(b,0,sizeof(b));
scanf("%d",&t);
cnt=1;
a[1]=t;
b[1]++;
maxn=b[1];
ans=a[1];
for(j=2;j<=n;j++)
{
scanf("%d",&t);
for(i=1;i<=cnt;i++)
{
if(t==a[i])
{
b[i]++;
if(b[i]>maxn)
{
maxn=b[i];
ans=a[i];
}
break;
}
}
if(i==cnt+1)
{
a[++cnt]=t;
b[cnt]++;
}
}
printf("%d\n",ans);
}
return 0;
}
算法训练 最小乘积(基本型)
时间限制:1.0s 内存限制:512.0MB
问题描述
给两组数,各n个。
请调整每组数的排列顺序,使得两组数据相同下标元素对应相乘,然后相加的和最小。要求程序输出这个最小值。
例如两组数分别为:1 3 -5和-2 4 1
那么对应乘积取和的最小值应为:
(-5) * 4 + 3 * (-2) + 1 * 1 = -25
输入格式
第一个行一个数T表示数据组数。后面每组数据,先读入一个n,接下来两行每行n个数,每个数的绝对值小于等于1000。
n<=8,T<=1000
输出格式
一个数表示答案。
样例输入
2
3
1 3 -5
-2 4 1
5
1 2 3 4 5
1 0 1 0 1
样例输出
-25
6
#include <iostream>
#include <algorithm>
using namespace std;
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int T,i,n,sum,a[10],b[10];
cin>>T;
while(T--){
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<=n;i++)
cin>>b[i];
sort(a+1,a+n+1);
sort(b+1,b+n+1,cmp);
sum = 0;
for(i=1;i<=n;i++)
sum+=a[i]*b[i];
cout<<sum<<endl;
}
return 0;
}