N诺刷题——进制转换、排版、日期

简单模拟

1020

最长连续因子,简单

1021

水题

进制转换类问题

1461反序相等

设N是一个四位数,它的9倍恰好是其反序数(例如:1234 的反序数是4321),求N的值。
原代码

#include
using namespace std;
#include 
int main()
{
	int fanxu=0;
	for (int i=1000;i<=9999;i++)
	{
		fanxu=i/1000+(i%1000/100)*10+
			(i%100/10)*100+(i%10)*1000;
		if (i*9==fanxu)
			cout<<i<<endl;
	}
	system("pause");
	return 0;
}

改进后
对反序输出的改进

#include
using namespace std;
#include 
int main()
{
	int num=0,x;
	for (int i=1000;i<=9999;i++)
	{
		x=i*9;
		num=0;
		while(x)
		{
			num=num*10+x%10;
			x=x/10;
		}
		if(num==i)
			cout<<i<<endl;
	}
	system("pause");
	return 0;
}

1259

写出一个程序,接受一个十六进制的数值字符串,输出该数值的十进制字符串(注意可能存在的一个测试用例里的多组数据)。

//#include 
#include
#include //记录错误,这里原先是#include 
using namespace std;
/*
一般一个C++的老的带“.h”扩展名的库文件,比如iostream.h,在新标准后的标准库中都有
一个不带“.h”扩展名的相对应,区别除了后者的好多改进之外,还有一点就是后者的东东都
塞进了“std”名字空间中。 

但唯独string特别。 
问题在于C++要兼容C的标准库,而C的标准库里碰巧也已经有一个名字叫做“string.h”的头
,包含一些常用的C字符串处理函数,比如楼主提到的strcmp。 
这个头文件跟C++的string类半点关系也没有,所以并非的“升级版
本”,他们是毫无关系的两个头文件。
因此都要包含
 */


int main()
{
	char s[105];
	while(cin>>s)
	{
		int len=strlen(s);
		int ans=0;
		for (int i=2;i<len;i++)
		{
			ans=ans*16;
			if(s[i]>='0'&&s[i]<='9')
				ans=ans+(s[i]-'0');
			else if (s[i]>='A')
				ans=ans+10+(s[i]-'A');
		}

		cout<<ans<<endl;
	}
	//system("pause");
	return 0;
}

1178

将一个长度最多为30位数字的十进制非负整数转换为二进制数输出

#include
#include 
using namespace std;
int main()
{
	char s[50];
	int turn[100];
	while(cin>>s)
	{
		int i=0, len=strlen(s), flag=0,flag2=0;//主要用来判断0
		while(flag!=len)
		{
	
			if((s[len-1]-'0')%2==0)
				turn[i]=0;
			else
				turn[i]=1;
			
			while(s[flag]=='0')
				flag++;	
			if(flag==len)
				break;
			flag2=1;

			for(int j=flag;j<len;j++)
			{
				if((s[j]-'0')%2==0)
					s[j]=(s[j]-'0')/2+'0';
				else
				{
					s[j]=(s[j]-'0')/2+'0';
					if(j!=len-1)
						s[j+1]=10+s[j+1];
				}
			}
			i++;
		}
		if(flag2==0)
			cout<<0<<endl;
		else{
			for (int d=i-1;d>=0;d--)
			{
				cout<<turn[d];
			}
			cout<<endl;
		}
	}
	return 0;
}

改进版本1

#include
#include 
using namespace std;
int main()
{
	char s[50];
	int turn[100];
	while(cin>>s)
	{
		int i=0, len=strlen(s), flag=0,flag2=0;
		while(flag!=len)
		{

			if((s[len-1]-'0')%2==0)
				turn[i]=0;
			else
				turn[i]=1;
			
			while(s[flag]=='0')
				flag++;	
			if(flag==len)
				break;
			flag2=1;

			for(int j=flag;j<len;j++)
			{
				if((s[j]-'0')%2==0)
					s[j]=(s[j]-'0')/2+'0';
				else
				{
					s[j]=(s[j]-'0')/2+'0';
					if(j!=len-1)
						s[j+1]=10+s[j+1];
				}
			}
			i++;
		}
		if(flag2==0)
			cout<<0<<endl;
		else{
			for (int d=i-1;d>=0;d--)
			{
				cout<<turn[d];
			}
			cout<<endl;
		}
	}
	return 0;
}

改进版本

#include 
#include 
#include 
using namespace std;

string divide(string str){
	int remainder=0;
	for(int i=0;i<str.size();i++){
		int current =remainder*10+str[i]-'0';
		str[i]=current/2+'0';
		remainder=current%2;
	}
	int i=0;
	while(str[i]=='0')
	i++;
	return str.substr(i);//只有一个数字5表示从下标为5开始一直到结尾:
}

int main() {
	string str;
	while(cin>>str){
		vector<int>binary;
		while(str.size()!=0){
			int yushu;
			yushu=(str[str.size()-1]-'0')%2;
			binary.push_back(yushu);
			str=divide(str);
		}
		for(int i=(binary.size()-1);i>=0;i--)
		printf("%d",binary[i]);
		printf("\n");
	}
	return 0;
}

1176

不知为何通过了牛客网测试 未通过N诺测试
原来是N诺的题目没说清楚,是要连续输入

#include
#include 
#include 
#include 
using namespace std;

string chufa(string s)
{
	int jiewei=0;
	for(int i=0;i<s.size();i++)
	{
		int temp=jiewei*10+s[i]-'0';
		s[i]=temp/2+'0';
		jiewei=temp%2;
	}
	int j=0;
	while(s[j]=='0')
		j++;
	return s.substr(j);
}

string jiafa(string s1,string s2)//默认s1长于s2
{
	string s3=s1+"0";//生成多一位数
	int jinwei=0,temp=0;
	for (int i=s1.size()-1;i>=0;i--)
	{
		if(i>=s1.size()-s2.size())
		{
			temp=jinwei+s1[i]-'0'+s2[i-s1.size()+s2.size()]-'0';
		}
		else
		{
			temp=jinwei+s1[i]-'0';
		}
		s3[i+1]=temp%10+'0';
		jinwei=temp/10;
	}
	if(jinwei==1)
		s3[0]='1';
	else
		s3=s3.substr(1);
	return s3;
}

int main()
{
	string s;
	string s2="0";
	cin >>s;
	vector<int>a;
	while(s.size()!=0)
	{
		int yushu=(s[s.size()-1]-'0')%2;
		a.push_back (yushu);
		s=chufa(s);//求商操作
	}
	for(int i=0;i<a.size();i++)//已经是逆序了
	{
		if(a[i]==0)
			s2=jiafa(s2,s2);
		else
		{
			s2=jiafa(s2,s2);
			s2=jiafa(s2,"1");
		}
	}
	cout<<s2<<endl;
	//system("pause");
}

1380、1417没什么好说

1422直接是将两个转换合起来,没什么好说

1097负进制问题

主要是要明白负进制也是使用进制转换的算法
N诺刷题——进制转换、排版、日期_第1张图片
然后一直没通过的原因是因为忘记了处理0

#include
#include 
#include 
#include 
using namespace std;

int main()
{
	int m;
	while(cin>>m)
	{
		if(m==0)
		{
			cout<<0<<endl;
			continue;
		}
		vector<int>a;
		while(m!=0)
		{
			int shang=m/(-2);
			if((m-shang*(-2))<0)
				shang++;
			a.push_back ((m-shang*(-2)));
			m=shang;
		}
		for(int i=a.size()-1;i>=0;i--)
			cout<<a[i];
		cout<<endl;
	}
	//system("pause");
	return 0;
}

排版类问题

总结:
先在纸上找找规律

1473字符菱形

很简单没什么好说的

1062、1392杨辉三角形

直接找规律,数字游戏,没啥好说

1377旋转矩阵

任意输入两个9阶以下矩阵,要求判断第二个是否是第一个的旋转矩阵,如果是,输出旋转角度(0、90、180、270),如果不是,输出-1。 要求先输入矩阵阶数,然后输入两个矩阵,每行两个数之间可以用任意个空格分隔。行之间用回车分隔,两个矩阵间用任意的回车分隔。

本题教训
1、搞清楚函数如何传二维数组
2、不允许返回二维数组
3、数组作为参数,对函数中数组的修改等于对原数组的修改
4、函数思想 ,这样下来层次分明

#include
#include 
#include 
#include 
using namespace std;

//旋转90度
void xuanzhuan(int s1[][9],int n)
{
	int s3[9][9];
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			s3[i][j]=s1[i][j];
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			s1[i][j]=s3[n-1-j][i];

}

//检查数组是否相等
bool check(int s1[][9],int s2[][9],int n)
{
	for (int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			if(s1[i][j]!=s2[i][j])
				return false;
	return true;
}

int main()
{
	int n;
	int s1[9][9];
	int s2[9][9];

//输入
	while(cin>>n)
	{
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				cin>>s1[i][j];
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				cin>>s2[i][j];

		int i,flag=0;
		//分别选择0次 1次 2次 3次 
		for(i=0;i<4;i++)
		{
			if(check(s1,s2,n))//判断是否相等
			{
				cout<< i*90<<endl;
				flag=1;
			}
			xuanzhuan(s1,n);//对s1进行旋转

		}
		if(i==4&&flag==0)//无解
			cout<<-1<<endl;
	}
	return 0;
}

1216旋转方阵

1 16 15 14 13
2 17 24 23 12
3 18 25 22 11
4 19 20 21 10
5 6 7 8 9

这种题目主要就是找规律

#include
#include 
#include 
#include 
using namespace std;

void gouzhao(int a[][20],int i,int n,int &jishu)
{
	
	int ax=(n-i)/2, ay=(n-i)/2;
	int bx=(n+i)/2-1,by=(n-i)/2;
	int cx=(n+i)/2-1,cy=(n+i)/2-1;
	int dx=(n-i)/2,dy=(n+i)/2-1;

	a[ax][ay]=jishu;
	for (int k=ax;k<bx;k++)//填充上面
		a[k][ay]=a[ax][ay]+k-ax;
	for(int k=by;k<cy;k++)//填充下面
		a[bx][k]=a[bx-1][by]+k-by+1;
	for(int k=cx;k>dx;k--)//填充右边
		a[k][cx]=a[cx][cy-1]+cx-k+1;
	for (int k=dy;k>ay;k--)//填充上边
		a[dx][k]=a[dx+1][dy]+dy-k+1;
	jishu =a[ax][ay+1]+1;

}
int main()
{
	int n;
	int a[20][20];
	while(scanf("%d",&n) != EOF)
	{
		int jishu=1;
		for (int i=n;i>=1;i=i-2)//每次循环构造一层,i为该层的边长
		{
			gouzhao(a,i,n,jishu);
		}

		for(int i=0;i<n;i++)
		{
			for (int j=0;j<n;j++)
				printf("%-4d",a[i][j]);
			printf("\n");
		}
	}
	system("pause");
	return 0;
}

改进版本
对循环的改进,使用while循环

#include
#include 
#include 
#include 
using namespace std;

int main()
{
	int n;
	int a[20][20];
	while(scanf("%d",&n) != EOF)
	{
		int a_x=0,a_y=0,b_x=n-1,b_y=n-1;
		int cnt=1;
		while(a_x<b_x)
		{
			int i=a_x,j=a_y;	
			while(i<b_x)
				a[i++][j]=cnt++;
			while(j<b_y)
				a[i][j++]=cnt++;
			while(i>a_x)
				a[i--][j]=cnt++;
			while(j>a_y)
				a[i][j--]=cnt++;
			a_x++;a_y++;b_x--;b_y--;
		}
		if(n%2)
			a[n/2][n/2]=cnt;

		for(int i=0;i<n;i++)
		{
			for (int j=0;j<n;j++)
				printf("%-4d",a[i][j]);
			printf("\n");
		}
	}
	system("pause");
	return 0;
}

日期类问题

总结:直接用暴力计算日期差值

1011计算星期

没什么东西

1290 日期差值

直接加,加到相等为止,暴力算法

#include
#include 
using namespace std;

int main()
{
	int month[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}
	};
	int num1,num2;
	while(cin>>num1)
	{
		cin>>num2;
		int cnt=1;
		if(num1>num2)//进行交换 确保num1最大
		{
			int temp=num1;
			num1=num2;
			num2=temp;
		}
		int year1=num1/10000,month1=num1%10000/100,day1=num1%100;
		int year2=num2/10000,month2=num2%10000/100,day2=num2%100;
		int num1=0,num2=0;
		while(!(year1==year2&&month1==month2&&day1==day2))
		{
			//判断闰年
			int flag=0;
			if((year1%400==0)||(year1%4==0)&&(year1%100!=0))
				flag=1;
			else 
				flag=0;

			day1++;
			cnt++;
			if(day1>month[flag][month1])
			{
				day1=1;
				month1++;
				if(month1>12)
				{
					month1=1;
					year1++;
				}
			}
		}
		cout<<cnt<<endl;
	}
	//system("pause");
	return 0;
}

其他的解法,比较算出和000年0月0日的差值,然后相减亦可

1410

给出年分m和一年中的第n天,算出第n天是几月几号。
和上题一样 暴力算法
记录错误:因为输入那里忘记加EOF导致出现Output Limit Exceeded错误:输出超限,出现这个错误的原因一般是你的程序输出内容超过了题目答案长度的2倍以上,一般情况是忘记注释掉调试信息。

#include
#include 
using namespace std;

int main()
{
	int m,n;
	int month[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",&m,&n)!=EOF)
	{
		int mon=1;
		int day=1;
		while(n-1>0)
		{
			//判断闰年
			int flag=0;
			if((m%400==0)||(m%4==0)&&(m%100!=0))
				flag=1;
			else 
				flag=0;

			day++;
			if(day>month[flag][mon])
			{
				day=1;
				mon++;
			}
			n--;
		}
		printf("%d-%02d-%02d\n",m,mon,day);
	}
	//system("pause");
	return 0;
}

本题亦可直接相减

#include
using namespace std;

int IsLeapYear(int year){   //判断是否为闰年,因为闰年天数和平年天数不同,需要区分
    if (year % 4 == 0 && year % 100 != 0)  return 1;
    if (year % 400 == 0)  return 1;
    return 0;
}
int yuetianshu[2][13] = {   //0行为平年,2月28天;1行为闰年,2月29天;
    {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}
};

int main(){
    int year,month,day,sum;
    int i = 1;
    while (cin >> year >> sum){   //题目要求多次输入
        for (i = 1; sum > yuetianshu[IsLeapYear(year)][i]; i++){   //sum如果大于该月天数,说明月份还要增加
            sum -= yuetianshu[IsLeapYear(year)][i];
        }
        month = i;   //此时的i正好就是月份
        day = sum;   //此时的sum正好就是day
        printf("%d-%02d-%02d\n",year,month,day);
    }
    return 0;
}

1437日期类

注意这个数组的初始化

#include
#include 
using namespace std;
class date
{
public:
	int month[13];
	//对日期加1
	void increase(int year,int mon,int day)
	{
		if((year%400==0)||(year%4==0)&&(year%100!=0))
			month[2]=29;
		else
			month[2]=28;
		day++;
		if(day>month[mon])
		{
			day=1;
			mon++;
		}
		printf("%d-%02d-%02d\n",year,mon,day);
	}
	date()
	{
		month[0]=0;month[1]=31;month[2]=28;month[3]=31;month[4]=30;month[5]=31;month[6]=30;month[7]=31;
		month[8]=31;month[9]=30;month[10]=31;month[11]=30;month[12]=31;
	}
};

int main()
{
	int m;
	int year,mon,day;
	scanf("%d",&m);

	while(m>0)
	{
		scanf("%d %d %d",&year,&mon,&day);
		date d;
		d.increase (year,mon,day);
		m--;
	}
	//system("pause");
	return 0;
}

1446

日期累加

#include
#include 
using namespace std;

int main()
{
	int month[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}
	};
	int m;
	int year,mon,day,cnt;
	scanf("%d",&m);
	while(m>0)
	{
		scanf("%d %d %d %d",&year,&mon,&day,&cnt);		
		while(cnt>0)
		{
			//判断闰年
			int flag=0;
			if((year%400==0)||(year%4==0)&&(year%100!=0))
				flag=1;
			else 
				flag=0;

			day++;
			if(day>month[flag][mon])
			{
				day=1;
				mon++;
				if(mon>12)
				{
					mon=1;
					year++;
				}
			}
			cnt--;
		}
		printf("%d-%02d-%02d\n",year,mon,day);
		m--;
	}
	//system("pause");
	return 0;
}

1053 偷菜时间表

简单没什么可以说的

你可能感兴趣的:(#,N诺网站)