[牛客练习赛65]补题
A 贪心
瞎猜,小的用来加,大数用来乘
#include <bits/stdc++.h> using namespace std; #define ll long long const int N = 5e5+5; const int MOD = 998244353; ll b[N]; int main() { int n; cin>>n; for(int i=0;i<n;++i) cin>>b[i]; sort(b,b+n); ll ans=0; for(int i=0;i<n/2;++i){ ans = (ans+b[i])%MOD; } for(int i=0;i<n/2;++i){ ans = (ans*b[i+n/2])%MOD; } cout<<ans%MOD; }
B 快速幂
把每个数表示成k的多少次方,k^a*k^b=a+b 比较a+b的大小即可,本来想用log函数。。结果超时
pow函数用inline才能过....还不如for循环快
#include <bits/stdc++.h> using namespace std; #define int long long #define ll long long #define MYINTMAX 0x3f3f3f3f const int N = 5e5+5; const int MOD = 998244353; int mod; inline ll myPow(ll a,ll b){ ll base=a;ll ans=1; while(b>0){ if(b&1) ans=ans*base%mod; base=base*base%mod; b>>=1; } return ans%mod; } //把每个数表示成k的多少次方,k^a*k^b=a+b 比较a+b的大小即可,本来想用log函数。。结果超时 ll a[2001][2001]; signed main() { int n,m,k; cin>>n>>m>>k>>mod; int ans=0;ll x; for(int i=0;i<n;++i){ int tmp=0; for(int j=0;j<m;++j){ scanf("%lld",&x); int exponent=0; while (x!=1){ exponent++; x/=k; } tmp+=exponent; } ans=max(tmp,ans); } int sum=myPow(k,ans)%mod; cout<<sum<<endl; return 0; }
C 极角排序,计算几何
我们平常所使用的坐标系都是直角坐标系,而极角排序是在极坐标系下进行的。
这里首先要选取一个点,然后其它点根据与参考点的连线与x轴所成的夹角的大小进行排序的。
这里我们可以简单理解为绕着一个点逆时针转圈访问。
夹角排序,可以理解为斜率排序,这个题是以(0,0)为中心则(x,y)斜率为y/x; 斜率比较则为
做的时候想到了答案只有-1,0,1,2,3 0,1很好判断,1就是存在斜率相同的点,但没想到是按斜率排序然后二分查找
2,3并没有想到好办法去判断 = =
看题解才会系列:
画图可以发现如果n > 2一定输出2
如果n=2,只有当询问点,(0,0)和两个点构成了一个平行四边形时会输出3,否则输出2
#include<bits/stdc++.h> #define N 100005 using namespace std; typedef long long ll; int n,q; struct point{ ll x,y; point(){} point(ll x,ll y):x(x),y(y){} point operator +(const point&a)const { return point(x+a.x,y+a.y);} point operator -(const point&a)const { return point(x-a.x,y-a.y);} ll operator ^(const point&a)const {return x*a.y-y*a.x;}// 斜率比较 bool operator == (const point &a)const {return (x==a.x)&&(y==a.y);} bool operator <(const point &a)const { return (x * a.y - y * a.x)>0;} }pt[N]; bool same(point a,point b) { return ((a ^ b) == 0); } int main() { scanf("%d%d",&n,&q); for(int i=1;i<=n;++i) { scanf("%lld%lld",&pt[i].x,&pt[i].y); if(pt[i].x == 0 && pt[i].y == 0) --i,--n; } sort(pt + 1,pt + n + 1); bool line = same(pt[1],pt[n]);//所有的点都在同一条线上 while(q--) { point a; scanf("%lld%lld",&a.x,&a.y); if(a.x == 0 && a.y == 0) { printf("0\n"); continue; } int it = lower_bound(pt + 1,pt + n + 1,a) - pt; // 二分找斜率相同的点 if(1 <= it && it <= n && same(pt[it] , a)) { printf("1\n"); continue; } if(line) { printf("-1\n"); continue; } if(n > 2) { printf("2\n"); continue; } if(a == (pt[1] + pt[2])) printf("3\n");//构成了一个平行四边形时输出3 else printf("2\n"); } return 0; }