题意:
输入n,再输入n个数。输出每个数(x)可以和其他n-1个数(y)形成 x^y > y^x 的情况有几种。
解题思路:
x^y > y^x
<=> lnx^y > ln y^x
<=> lnx/x > y/lny
也就是说,只要判断x/lnx这个函数的单调性即可(做函数图像的e为该函数的最大值)
注意点:
①这n个数中有重复的,所以1,2,3特殊考虑,并且倒序输出
②临界点:ln1/1=0,ln2/2=ln4/4(2^4 == 4^2)
代码中一些变量名称对应的意义:
ccnt[i]...记录i出现的次数
nowcnt...记录当前数字重复的个数,当前遍历到的数与上一个不同数,当前ans=上个ans+nowcnt
下面是代码:
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
struct node
{
int num,id;
int ans;
}a;
vector<node>v;
bool cmp1(const node& a,const node& b){return a.num<b.num;}
bool cmp2(const node& a,const node& b){return a.id<b.id;}
int main()
{
int n;
int ccnt[5]={0};
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d",&a.num);
a.id=i;
a.ans=0;
v.push_back(a);
if (a.num<=4) ccnt[a.num]++;
}
sort(v.begin(),v.end(),cmp1);
int cnt=v.size();
int nowcnt=0;
for (int i=cnt-1;i>=0;i--){
if (v[i].num==1){
v[i].ans=0;
}
else if (v[i].num==2){
v[i].ans = cnt-ccnt[4]-ccnt[3]-ccnt[2];
}
else if (v[i].num==3){
v[i].ans = cnt-ccnt[3];
}
else {
if (i==cnt-1) v[i].ans = ccnt[1],nowcnt++;
else if (v[i].num == v[i+1].num) v[i].ans = v[i+1].ans,nowcnt++;
else v[i].ans = v[i+1].ans+nowcnt,nowcnt=1;
}
}
sort(v.begin(),v.end(),cmp2);
for (int i=0;i<v.size();i++)
if (i!=0) printf(" %d",v[i].ans);
else printf("%d",v[i].ans);
printf("\n");
return 0;
}
思路是大佬给的,大佬还是大佬啊。