题目来源于塔子哥自建的网站当然也可以去大佬主页看看@塔子哥来了
1.整数排序
题目内容
输入若干个int类型整数,将整数按照位数由大到小排序,如果位数相同,则按照整数本身从小到大排序。
例如,
输入:10 -3 1 23 89 100 9 -123
输出:-123 100 10 23 89 -3 1 9
输入的整数个数最多不超过1e6个。
输入格式
在一行中输入若干个整数,整数之间用一个空格分隔。
输出格式
在一行中输出排序好的整数,整数之间用一个空格分隔。
样例
input
10 -3 1 23 89 100 9 -123
ouput
-123 100 10 23 89 -3 1 9
input
1 -2 12
ouput
12 -2 1
分析:写个cmp函数,对长度先比较,然后再对数字大小比较。注意0的情况即可。不过做这道题的时候,已经忘了cmp做法,后面看了题解,才回忆起这样做。
#include<bits/stdc++.h>
using namespace std;
struct digit{
int x;
int len;
}a[10001000];
int getlen(int idx)
{
int no=0;
int idx1=abs(idx);
while(idx1!=0)
{
no++;
idx1/=10;
}
return no;
}
int cmp(const digit &x,const digit &y)
{
if(x.len>y.len)
return true;
else if(x.len<y.len)
return false;
else
{
if(x.x>y.x)
return false;
else
return true;
}
}
int main()
{
int i=0,l=0;
while(cin>>l)//&&l!=EOF)
{
a[i].x=l;
a[i].len=getlen(l);
if(l==0)
a[i].len=1;
i++;
}
sort(a,a+i,cmp);
for(int j=0;j<i;j++)
{
cout<<a[j].x;
if(j!=i-1)
cout<<" ";
}
return 0;
}
2.位运算
题面
给定一个int型整数xx,将xx的二进制表示中第i位和第j位的值互换。0 \leq i,j \leq 310≤i,j≤31
注意: xx的二进制表示的最右边为第0位。
输入格式
在一行中输入三个整数,x,i,jx,i,j, 整数之间用一个空格分隔。
输出格式
在一行中输出互换后的结果
样例
input
38 2 4
ouput
50
input
1 0 2
ouput
4
思路:通过个数组存储n转化为2进制的数,然后交换ij位置即可。当然可以看塔子哥的csdn题解,简洁很多。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int x,i,j;
int a[40];
while(cin>>x>>i>>j)
{
memset(a,0,sizeof(a));
int k=x,len=0,ans=0;
while(k)
{
if(k%2==0)
a[len]=0;
else
a[len]=1;
len++;
k/=2;
}
int cc=a[i];
a[i]=a[j];
a[j]=cc;
int cnt=0;
for(int s=0;s<=31;s++)
{
ans+=pow(2,cnt)*a[s];
cnt++;
//cout<<ans<<endl;
}
if(x<0)
ans*=-1;
cout<<ans<<endl;
}
return 0;
}
3.差分计数
分析:可以通过哈希表来做,跟力扣上面的560题很类似,可以看看我写的LeetCode560题解,本题我用了自带的哈希表,也还用了模拟哈希表来做,算是一种尝试,放在代码中了。
代码
#include<bits/stdc++.h>
#include<map>
#define maxn 2001000
using namespace std;
int a[maxn];
int b[maxn*2];
int add2e6(int x)
{
return x+2e6;
}
int main()
{
int n,x;
long long ans=0;
cin>>n>>x;
for(int i=0;i<n;i++)
{
cin>>a[i];
b[add2e6(a[i])]++;
}
for(int i=0;i<n;i++)
{
if(b[add2e6(a[i])-x]!=0)
ans+=b[add2e6(a[i])-x];
}
cout<<ans<<endl;
// unordered_map<int,int> mp;
// int n,x,a,ans=0;
// cin>>n>>x;
// for(int i=0;i<n;i++)
// {
// cin>>a;
// mp[a]++;
// }
// for(auto iter=mp.begin();iter!=mp.end();++iter)
// {
// int idx=iter->first;
// if(mp.find(idx-x)!=mp.end())
// ans+=mp[idx-x];
// }
// cout<<ans<<endl;
return 0;
}
4.罗马数字
分析:做之前例举了一下样例的情况,但是没有得出结论。后面看了题解,发现就是道简单的模拟,我真的是大呼上当,自己给自己设置难度了。算是也复习了一下switch case的写法。
这张图片来源于塔子哥知乎的讲解。真的写的很清晰,一看就明白咋回事了。
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
string ans;
string I="I",V="V",X="X",L="L",C="C",D="D",M="M";
int n;
cin>>n;
while(n!=0)
{
if(n/10==0)
{
switch (n){
case 1:ans+="I";break;
case 2:ans+="II";break;
case 3:ans+="III";break;
case 4:ans+="IV";break;
case 5:ans+="V";break;
case 6:ans+="VI";break;
case 7:ans+="VII";break;
case 8:ans+="VIII";break;
case 9:ans+="IX";break;
case 10:ans+="X";break;
}
n=0;
}
else if(n/100==0)
{
switch (n/10){
case 1:ans+="X";break;
case 2:ans+="XX";break;
case 3:ans+="XXX";break;
case 4:ans+="XL";break;
case 5:ans+="L";break;
case 6:ans+="LX";break;
case 7:ans+="LXX";break;
case 8:ans+="LXXX";break;
case 9:ans+="XC";break;
case 10:ans+="C";break;
}
n%=10;
}
else
{
switch (n/100){
case 1:ans+="C";break;
case 2:ans+="CC";break;
case 3:ans+="CCC";break;
case 4:ans+="CD";break;
case 5:ans+="D";break;
case 6:ans+="DC";break;
case 7:ans+="DCC";break;
case 8:ans+="DCCC";break;
case 9:ans+="CM";break;
case 10:ans+="M";break;
}
n%=100;
}
}
cout<<ans<<endl;
return 0;
}