**题目描述:**a、b、c均为0~9的数字,求满足abc + bcc = 532的所有值。
#include
#include
using namespace std;
int main()
{
int a, b, c;
for (a = 0; a < 10; a ++) {
for (b = 0; b < 10; b ++) {
for (c = 0; c < 10; c ++) {
if (a * 100 + b * 110 + c * 12 == 532) {
printf("%d %d %d",a, b, c);
//<
}
}
}
}
return 0;
}
题目描述:N是一个4位数,他的9倍恰好是其反序数,求N的值。
思路:首先考虑反序数的求法,四位数对10进行取整,取到个位数值,然后再/10,依次取到十百千位上的数值。每一次都乘以10+上一位取出来的数值。
#include
#include
using namespace std;
//首先定义一个求逆序数的函数
int number_reverse(int n) {
int remain;//存放整除后的值
int _reverse = 0;//存放逆序数
while (n != 0) {//4321->432->43->4
remain = n % 10; //1->2->3->4
_reverse = _reverse * 10 + remain;//1->12->123->1234
n = n / 10;
}
return _reverse;
}
int main() {
int n;
for (n = 1000; n <= 9999; n ++) {
if (n == 9 * number_reverse(n) ) {
printf("%d\n", n);
//cout<
}
}
return 0;
}
题目描述:打印所有不超过256,平方具有对称性质的数。如2和11就是这样的数,因为22=4,1111=121
思路:所谓的对称数就是逆序数等于自身的数,这道题的意思就是求一个数
例如数为A,满足A^2 == τ(A^2)。
#include
#include
using namespace std;
//例题2.3,对称平方数1
//打印所有不超过256,其平方具有对称性质的数。即一个数的平方等于平方的逆序数。
//用于求所有不超过256的数的逆序数
求n的逆序数
//int count_reverse(int n) {
// int _reverse = 0; //用于存放逆序数
// int remain; //存放余数
// while(n > 0) {
// remain = n % 10;
// n = n / 10;
// _reverse = _reverse*10 + remain;
// }
// return _reverse;
//}
//int main()
//{
// int n;
// for(n = 0; n <= 256; n++) {
// int res = count_reverse(n*n);
// if(res == n*n){
// cout<
// }else continue;
// }
// return 0;
//}
//求逆序数
int number_reverse(int n) {
int remain;
int _reverse = 0;
while (n > 0) {
remain = n % 10;
_reverse = _reverse * 10 + remain;
n /= 10;
}
return _reverse;
}
int main() {
for (int i = 0; i < 265; i ++) {
if (i * i == number_reverse(i*i)) {
printf("%d\n", i);
}
}
}
题目描述: 一个正整数,如果能被7整除或者其十进制表示法中某个位数上为7,则称其为与7有关的数。求所有小于等于n(n < 100)的与7无关的正整数的平方和。
思路:重点在于如何求与7无关的数。
#include
#include
using namespace std;
//习题2.1和7无关的数
//构造一个函数用于判断输入的整数是否和7有关
int Judge(int n) {
int flag = 0;
if (n % 7 == 0) {
flag = 1;
}
while (n > 0) {
if (n % 10 == 7) {
flag = 1;
}
n /= 10;
}
return flag;
}
int main() {
int n;
int sum = 0;//用于存放与7无关的正整数的平方和
while (scanf("%d", &n) != EOF) {
for (int i = 0; i <= n; i ++ ) { //从0开始到n取数
if (0 == Judge(i)) {//若与7无关
sum = sum + i*i;
}
}
printf("%d\n",sum);
}
return 0;
}
题目描述:小于等于n元买100只鸡,大鸡5元,小鸡2元,1/3元一只的小小鸡,分别记为x、y、z只,求所有可能的解x,y,z。
思路:其实就是求三元一次方程的解。
#include
#include
using namespace std;
//百鸡问题
//小于等于n元买100只鸡,大鸡5元,小鸡2元,1/3元一只的小小鸡,分别记为x、y、z只,求所有可能的解
//三元一次方程的解
int main() {
int x, y, z;//整数存放鸡的只数
float n;//费用
while (scanf("%f", &n)) {
for (x = 0; x < 100; x ++) {
for (y = 0;y < 100-x; y ++) {
z = 100 - x - y;
if (15*x+6*y+z <= n) {
printf("%d %d %d\n",x, y, z);
}
}
}
}
return 0;
}
题目描述:N只火鸡的价格为$ XYZ,火鸡的总数N在1到99之间。价格由五位数组成,两边的数字由于褪色而看不清,所以只能看到中间的三位数。假设第一个数字非零,每只火鸡的价格是整数,并且所有火鸡的价格相同。给定N,X,Y和z,编写一个程序来猜测两边褪色的数字和火鸡的原始价格。如果有多个价格符合题意,那么输出最昂贵的那个。
思路:给定火鸡数量N以及总价中的十百千位数X、Y、Z,然后求万位数i和个位数j。注意总价和单价之间的关系,并且题目要求输出满足条件的火鸡的最大单价。
#include
#include
using namespace std;
int main() {
int n,x,y,z;
while (scanf("%d \n %d %d %d", &n, &x, &y, &z) != EOF) {
int price;
int max = 0,maxi,maxj;
for(int i = 1; i < 10; i++) {
for (int j = 0;j < 10; j++) {
price = i*1e4 + x*1e3 + y*1e2 + z*1e1 + j;
if (price%n == 0 && price > max*n) {//price满足被n整除, price>
max = price / n;//最大单价
maxi = i; //最大单价所对应的万位数
maxj = j; //最大单价所对应的个位数
}
}
}
if (max == 0)
printf("0 \n");
else
printf("%d %d %d\n", maxi, maxj, max);
}
return 0;
}
不知道为啥在本地的codeblock中无法进行用例输入,在oj中反而通过了。有点摸不着头脑,以后有空再琢磨琢磨,代码一个字没改突然又可以运行了。。。。。。
题目描述:输入h,输出一个高度为h,上底边长为h的梯形
思路:两种方法,一种是一行一行的分析,并且按规律输出。另外一种则是直接声明一个足够大得二维数组然后再进行填充。
方法一:h行,分析每一行的空格数和’ * '的数量,并且用i和h表示。
#include
#include
#include
using namespace std;
int main() {
int h;
while (scanf("%d", &h) != EOF) {
int i;
for (i = 0; i < h; i ++) {//一行一行输出
for (int j = 2*h-2*(i-1); j > 0; -- j) {
//先打印该行的空格
printf (" ");
}
for (int j = h+2*i; j > 0; -- j) {
//打印该行的*符号
printf("*");
}
printf("\n");
}
}
return 0;
}
方法二:声明一个足够大的二维数组来做。(!!!)
需要重点掌握,图形类的机试题归根结底就是打印一个二维数组,因此此方法是解决此类问题的通用解法。
#include
#include
#include
using namespace std;
//先声明一个足够大的字符数组
char arr[1000][3000];
int main()
{
int h;
while (scanf("%d", &h))
{
//先将整个数组赋值为空
for (int i = 0; i < h; i++)
{
for (int j = 0; j < 3*h-2; j++)
{
arr[i][j] = ' ';
}
arr[i][3*h-2] = '\0';//在每一行的行末填入一个终止符号'\0'
}
//在空数组中从第h-1行开始往上填入*号
int beg = 0;//用于指示每一行从哪里开始填充
for (int i = h-1; i >= 0; i--)
{
int j;
for (j = beg; j < 3*h-2; j ++)
{
arr[i][j] = '*';
}
beg = beg + 2;
}
//由于每一行的行末有终止符,故可以直接按行打印
for (int i = 0; i <= h; i ++)
{
printf("%s", arr[i]);
printf("\n");//换行符
}
}
return 0;
}
方法一:1990.9.20为例,先算1990.1.1 -> 1990.9.1 ->1990.9.20
从1.1到2.1中间的天数恰好是1月的天数。以此类推,1.1->9.1就是1+2+…+8月的天数totalday,
9.20就是今年的第totalday+20天。
总的来说这个方法局限比较大。
#include
#include
using namespace std;
//例题2.6 今年的第几天
//输入年月日,计算该天是今年的第几天
//1990.9.20为例
int main()
{
int year, mon, day;
int mday[13] = {0,31,28,31,30,31,30,31,30,31,30,31};
int totalDay[13] = {0}; //存放了从mon月1号到1~12月1号的天数
for (int mon = 2; mon <= 12; ++mon) {
//到mon月1日的天数 = 到mon-1月1日的天数+第mon-1月的天数
totalDay[mon] = totalDay[mon-1] + mday[mon-1];
}
while (scanf("%d %d %d",&year, &mon, &day) != EOF) {
bool isLeap = year%400 == 0 || year%100 != 0 && year%4 == 0;
if (isLeap == true && mon >= 3) {
printf("%d\n", totalDay[mon] + day + 1);
}else {
printf("%d\n",totalDay[mon] + day);
}
}
return 0;
}
方法二:nextday方法,解决日期问题的万能解法
int main() {
//输入年月日计算该天是今年的第几天
int year, mon, day;
int mday[2][13] ={
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};//每个月份的天数
while (scanf("%d%d%d",&year, &mon, &day)) {
int totalDay = 0; //用于计算累加天数
int row = (year%400 == 0 || year%100 != 0 && year%4 == 0);//判断是否为闰年
for (int i = 0; i < mon; i ++) {//加上该月份之前的所有月份天数
totalDay += mday[row][i];
}
totalDay += day;//再加上日
printf("%d", totalDay);
}
return 0;
}
题目描述:给出年份m和一年中的第n天,算出第n天是几月几号。按照yyyy-mm-dd的将对应的日期打印出来。
//方案二(日期的万能方案)
//最重要在于nextday的求法
//例题2.7打印日期
//输入年份和天数n并输出该年第n天的日期 yyyy-mm-dd
int main () {
int year, n;
int mday[13] = {-1,31,28,31,30,31,30,31,31,30,31,30,31};
//{-1,31,29,31,30,31,30,31,31,30,31,30,31}
//二维数组分别表示平年闰年的月份天数
while (scanf("%d%d",&year, &n)) {
//先判断是否是闰年
bool isLeap = (year%400 == 0|| (year%100 != 0 && year%4 == 0));//根据是否闰年选择mday的不同行
if (isLeap) {
mday[2] = 29;
}else {
mday[2] = 28;
}
//nextday
int day = 0,mon = 0;
for(int i = 0; i < n; i ++) {
++day;
if (day > mday[mon]) {
day = 1;
++mon;
if (mon > 12) {
mon = 1;
++year;
}
}
}
printf("%04d-%02d-%02d", year, mon, day);
}
return 0;
}
题目描述:计算一个日期加上若干天后是什么日期。
输入:输入第一行表示样例个数m,接下来的m行中,每行四个整数,分别表示年、月、日和累加天数。
输出:输出m行,每行按照yyyy-mm-dd的格式输出
#include
using namespace std;
//日期累加
//给定一个日期和天数n, 计算该日期n天后的日期按照yyyy-mm-dd格式输出
bool isLeap(int year) {
return year%400 == 0 || (year%100 != 0 && year%4 == 0);
}
int main()
{
int mday[2][13] = {
{-1,31,28,31,30,31,30,31,31,30,31,30,31},
{-1,31,29,31,30,31,30,31,31,30,31,30,31}
};
int year, mon, day;
int n;
int row;
row = isLeap(year);
//int ldaynumber;
while (scanf("%d%d%d%d",&year, &mon, &day, &n)) {
int endyear = year, endmon = mon, endday = day;
//nextday
for (int i = 0; i < n; ++i) {
++endday;
if (endday > mday[row][mon]) {
endday = 1;
++endmon;
if (endmon > 12) {
endmon = 1;
++endyear;
row = isLeap(endyear);
}
}
}
printf("%04d-%02d-%02d", endyear, endmon, endday);
}
return 0;
}
注意:printf输出时,无需加&符号,否则打印的是该变量的地址。
#include
using namespace std;
//例题2.9 剩下的树
int main()
{
int tree[10001] = {0};
int L, M;
while (scanf("%d%d",&L, &M) != EOF) {
for (int i = 0; i <= L; ++i) {//种下L+1棵树
tree[i] = 1;
}
while (M--) {//对M组数据进行处理
int Left, Right;
scanf("%d%d", &Left, &Right);
for (int i = Left; i <= Right; ++i) {
tree[i] = 0;
}
}
int num = 0;//初始化剩下的树的棵数
for (int i = 0; i <= L; ++i) {
if (tree[i]) ++num;
}
printf("%d", num);
}
return 0;
}
题目描述:按手机键盘输入字母的方式,计算所花费的时间 如:a,b,c都在“1”键上,输入a只需要按一次,输入c需要连续按三次。 如果连续两个字符不在同一个按键上,则可直接按,如:ad需要按两下,kz需要按6下 如果连续两字符在同一个按键上,则两个按键之间需要等一段时间,如ac,在按了a之后,需要等一会儿才能按c。 现在假设每按一次需要花费一个时间段,等待时间需要花费两个时间段。 现在给出一串字符,需要计算出它所需要花费的时间。
思路:知道手机九键的排列方式,如图:
需要注意的是7和9上有四个英文字母。据此需要一个keyMap用于指定每个字母所对应的键位,再用一个map用于指定每个字符输入时所花市场。
#include
#include
#include
using namespace std;
//例题2.10手机键盘
int main()
{
//声明一个字母和数字的对应map
map <char, int> keyMap {
{'a', 2},{'b', 2},{'c', 2},
{'d', 3},{'e', 3},{'f', 3},
{'g', 4},{'h', 4},{'i', 4},
{'j', 5},{'k', 5},{'l', 5},
{'m',6},{'n',6},{'o',6},
{'p',7},{'q',7},{'r',7},{'s',7},
{'t',8},{'u',8},{'v',8},
{'w',9},{'x',9},{'y',9},{'z',9}
};
//声明一个字母在该按键上要按的次数map
map <char, int> inputTime {
{'a', 1},{'b', 2},{'c', 3},
{'d', 1},{'e', 2},{'f', 3},
{'g', 1},{'h', 2},{'i', 3},
{'j', 1},{'k', 2},{'l', 3},
{'m',1},{'n',2},{'o',3},
{'p',1},{'q',2},{'r',3},{'s',4},
{'t',1},{'u',2},{'v',3},
{'w',1},{'x',2},{'y',3},{'z',4}
};
char str[101];
while (scanf("%s",str) != EOF) {
int lastInput = 1; //lastInput用于判断上一次按键是否与本次按键相同,初始化为1
int totalTime = 0;
for (int i = 0; str[i] != '\0'; ++ i) {
//先计算等待时长
if (keyMap[str[i]] == lastInput) {//若字符所在键位和上一次键位相同,等待时长+2
totalTime += 2;
}
//本字符按键所花时间
totalTime = totalTime + inputTime[str[i]];
lastInput = keyMap[str[i]];
}
printf("%d", totalTime);
}
return 0;
}
**题目描述:给定一个日期,计算给定日期是星期几,按照10 April 2000格式输入 **
#include
#include
#include
#include
using namespace std;
//例题2.7 DayofWeek
int main()
{
int year, mon, day;
char str[100];//C风格只用于scanf和printf
string month;
//一年当中1,3,5,7,8,10,12均为31天,4,6,9,11均为30天,2月则根据平年闰年为28或者29天
int mday[13] = {-1,31,28,31,30,31,30,31,31,30,31,30,31};
string intToweek[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
//由string取到int,即通过月份名称取月份数
map<string,int> monthToint =
{
{"January",1},
{"February",2},
{"March",3},
{"April",4},
{"May",5},
{"June",6},
{"July",7},
{"August",8},
{"September",9},
{"October",10},
{"November",11},
{"December",12},
};
// 9 October 2001
//scanf 要使用C风格
bool isBefore;//判断输入的日期是在当前日期之前还是之后
while (scanf("%d%s%d",&day, str, &year) != EOF)
{
month = str; //把字符串从C风格转换成C++风格
mon = monthToint[month];//从字符串到整数
if (year < 2023
|| 2023 == year && mon < 3
|| 2023 == year && 3 == mon && day < 9) {
isBefore = true;
}
else {
isBefore = false;
}
//从begin走到end
int begYear, begMon,begDay,endYear,endMon,endDay;
if (isBefore) {//给定日期在之前
begYear = year;
begMon = mon;
begDay = day;
endYear = 2023;
endMon = 3;
endDay = 9;
} else {
begYear = 2023;
begMon = 3;
begDay = 9;
endYear = year;
endMon = mon;
endDay = day;
}
int totalDay = 0;
while (true) {
if(begYear == endYear && begMon == endMon && begDay == endDay) {
break;
}
++totalDay;
//nextDay
bool isLeap = begYear % 400 == 0 || (begYear%100 != 0 && begYear%4 == 0);
if (isLeap) {
mday[2] = 29;
} else {
mday[2] = 28;
}
++begDay;
if (begDay > mday[begMon]) {
begDay = 1;
++begMon;
if (begMon > 12) {
begMon = 1;
++begYear;
}
}
}
if(isBefore) {
//若在当前日期之前,则(x+totalDay)%7 = 4 -> x = (11-totalDay%7)%7
printf("%s\n", intToweek[(11-totalDay%7)%7].c_str());
} else {
//若在当前日期之后,则有x = (4+totalDay)%7
printf("%s\n",intToweek[(4+totalDay)%7].c_str());
}
}
return 0;
}