本来不想打的,结果看着看着自己就打进去了(笑哭)
A.第k小数
记得上课讲过。这道题卡排序(但听说有人排序过了??)
#include <iostream> #include <map> #include <ctime> #include <vector> #include <climits> #include <algorithm> #include <random> #include <cstring> #include <cstdio> #include <map> #include <set> #include <bitset> #include <queue> #define inf 0x3f3f3f3f #define IOS ios_base::sync_with_stdio(0); cin.tie(0); #define rep(i, a, n) for(register int i = a; i <= n; ++ i) #define per(i, a, n) for(register int i = n; i >= a; -- i) #define ONLINE_JUDGE using namespace std; typedef long long ll; const int mod=1e9+7; template<typename T>void write(T x) { if(x<0) { putchar('-'); x=-x; } if(x>9) { write(x/10); } putchar(x%10+'0'); } inline int read(){ int x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if (ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ x = (x<<1) + (x<<3) + (ch^48); ch = getchar(); } return x * f; } ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} ll lcm(ll a,ll b){return a/gcd(a,b)*b;}; ll ksm(ll a,ll n){//看是否要mod ll ans=1; while(n){ if(n&1) ans=(ans*a)%mod; a=a*a%mod; n>>=1; } return ans%mod; } //============================================================== const int maxn=5e6+10; int t,n,k; int a[maxn]; int quick(int l,int r,int k){ int i=l,j=r,x=a[i]; while(i<j){ while(i<j&&a[j]>x){ j--; } if(i<j){ a[i++]=a[j]; } while(i<j&&a[i]<x){ i++; } if(i<j){ a[j--]=a[i]; } } a[i]=x; if(i==k) return a[i]; else if(k<i) return quick(l,i-1,k); else return quick(i+1,r,k); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif clock_t c1 = clock(); //=========================================================== t=read(); while(t--){ n=read(),k=read(); rep(i,1,n){ a[i]=read(); } int ans=quick(1,n,k); write(ans); putchar('\n'); } //=========================================================== std::cerr << "Time:" << clock() - c1 << "ms" << std::endl; return 0; }
还有一种利用stl的方法,也可以过。
#include <iostream> #include <map> #include <ctime> #include <vector> #include <climits> #include <algorithm> #include <random> #include <cstring> #include <cstdio> #include <map> #include <set> #include <bitset> #include <queue> #define inf 0x3f3f3f3f #define IOS ios_base::sync_with_stdio(0); cin.tie(0); #define rep(i, a, n) for(register int i = a; i <= n; ++ i) #define per(i, a, n) for(register int i = n; i >= a; -- i) #define ONLINE_JUDGE using namespace std; typedef long long ll; const int mod=1e9+7; template<typename T>void write(T x) { if(x<0) { putchar('-'); x=-x; } if(x>9) { write(x/10); } putchar(x%10+'0'); } template<typename T> void read(T &x) { x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} ll lcm(ll a,ll b){return a/gcd(a,b)*b;}; ll ksm(ll a,ll n){//看是否要mod ll ans=1; while(n){ if(n&1) ans=(ans*a)%mod; a=a*a%mod; n>>=1; } return ans%mod; } //============================================================== const int maxn=5e6+100; int a[maxn]; int t,n,k; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif clock_t c1 = clock(); //=========================================================== read(t); while(t--){ read(n),read(k); rep(i,1,n) read(a[i]); nth_element(a+1,a+k,a+n+1); write(a[k]); putchar('\n'); } //=========================================================== std::cerr << "Time:" << clock() - c1 << "ms" << std::endl; return 0; }
B.不平行的直线
一道练stl的题,要注意处理下横坐标相等的情况就行了,剩下的set去重即可。
#include <iostream> #include <map> #include <ctime> #include <vector> #include <climits> #include <algorithm> #include <random> #include <cstring> #include <cstdio> #include <map> #include <set> #include <bitset> #include <queue> #define inf 0x3f3f3f3f #define IOS ios_base::sync_with_stdio(0); cin.tie(0); #define rep(i, a, n) for(register int i = a; i <= n; ++ i) #define per(i, a, n) for(register int i = n; i >= a; -- i) //#define ONLINE_JUDGE using namespace std; typedef long long ll; const int mod=1e9+7; template<typename T>void write(T x) { if(x<0) { putchar('-'); x=-x; } if(x>9) { write(x/10); } putchar(x%10+'0'); } template<typename T> void read(T &x) { x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} ll lcm(ll a,ll b){return a/gcd(a,b)*b;}; ll ksm(ll a,ll n){//看是否要mod ll ans=1; while(n){ if(n&1) ans=(ans*a)%mod; a=a*a%mod; n>>=1; } return ans%mod; } //============================================================== struct Point{ ll x,y; Point(int xx,int yy){ x=xx,y=yy; } }; vector<Point> da; int n; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif clock_t c1 = clock(); //=========================================================== read(n); rep(i,1,n){ int x,y; read(x),read(y); da.push_back(Point{x,y}); } set<double> s; int flag=0; rep(i,0,n-1){ rep(j,0,n-1){ if(i==j) continue; if(da[i].x==da[j].x){ flag=1; } else s.insert((double)(da[i].y-da[j].y)/(da[i].x-da[j].x)); } } write(s.size()+flag); //=========================================================== std::cerr << "Time:" << clock() - c1 << "ms" << std::endl; return 0; }
C.丢手绢
因为对于一个小朋友,顺时针遍历所有小朋友的过程中,他和某一个小朋友的距离是一个凸函数,所以,考虑对每一个小朋友三分,求距离他最远的小朋友,然后取所有答案的最大值即可。
#include <iostream> #include <map> #include <ctime> #include <vector> #include <climits> #include <algorithm> #include <random> #include <cstring> #include <cstdio> #include <map> #include <set> #include <bitset> #include <queue> #define inf 0x3f3f3f3f #define IOS ios_base::sync_with_stdio(0); cin.tie(0); #define rep(i, a, n) for(register int i = a; i <= n; ++ i) #define per(i, a, n) for(register int i = n; i >= a; -- i) #define ONLINE_JUDGE using namespace std; typedef long long ll; const int mod=1e9+7; template<typename T>void write(T x) { if(x<0) { putchar('-'); x=-x; } if(x>9) { write(x/10); } putchar(x%10+'0'); } template<typename T> void read(T &x) { x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} ll lcm(ll a,ll b){return a/gcd(a,b)*b;}; ll ksm(ll a,ll n){//看是否要mod ll ans=1; while(n){ if(n&1) ans=(ans*a)%mod; a=a*a%mod; n>>=1; } return ans%mod; } //============================================================== const int maxn=100000+10; ll a[maxn]; int s; ll sum[maxn]; int n; int cal(int x,int y){ if(y<x) swap(x,y); return min(abs(sum[y]-sum[x]),abs(s-abs(sum[y]-sum[x]))); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif clock_t c1 = clock(); //=========================================================== read(n); rep(i,1,n) read(a[i]); rep(i,1,n){ sum[i]=sum[i-1]+a[i]; } s=sum[n]; int ans=0; rep(i,1,n){ int l=1,r=n; int res=0; while(l<=r){ int lm=l+(r-l)/3,rm=r-(r-l)/3; int lv=cal(i,lm),rv=cal(i,rm); if(lv<rv){ l=lm+1; res=rv; } else{ r=rm-1; res=lv; } } ans=max(res,ans); } write(ans); //=========================================================== std::cerr << "Time:" << clock() - c1 << "ms" << std::endl; return 0; }
D.二分
题目写着二分,实际考虑的是差分+离散化。参考校门外的数,每次读入之后,根据符号得到,定区间的左右坐标,然后,扫描一遍就行了。
#include <iostream> #include <map> #include <ctime> #include <vector> #include <climits> #include <algorithm> #include <random> #include <cstring> #include <cstdio> #include <map> #include <set> #include <bitset> #include <queue> #define inf 0x3f3f3f3f #define IOS ios_base::sync_with_stdio(0); cin.tie(0); #define rep(i, a, n) for(register int i = a; i <= n; ++ i) #define per(i, a, n) for(register int i = n; i >= a; -- i) //#define ONLINE_JUDGE using namespace std; typedef long long ll; const int mod=1e9+7; template<typename T>void write(T x) { if(x<0) { putchar('-'); x=-x; } if(x>9) { write(x/10); } putchar(x%10+'0'); } template<typename T> void read(T &x) { x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} ll lcm(ll a,ll b){return a/gcd(a,b)*b;}; ll ksm(ll a,ll n){//看是否要mod ll ans=1; while(n){ if(n&1) ans=(ans*a)%mod; a=a*a%mod; n>>=1; } return ans%mod; } //============================================================== const int maxn=200000+100; ll n; struct node{ ll pos,val; }da[maxn]; ll cnt; vector<ll> a; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif clock_t c1 = clock(); //=========================================================== read(n); rep(i,1,n){ ll pp; char op; read(pp),cin>>op; if(op=='.'){ da[cnt++]={pp,1}; da[cnt++]={pp+1,-1}; } if(op=='-'){ da[cnt++]={pp+1,1}; da[cnt++]={INT_MAX,-1}; } if(op=='+'){ da[cnt++]={pp,-1}; da[cnt++]={-INT_MAX,1}; } } sort(da,da+cnt,[](const node&a,const node&b){ return a.pos==b.pos?a.val<b.val:a.pos<b.pos; }); ll pos=0; ll ans=0; rep(i,0,cnt-1){ pos+=da[i].val; ans=max(ans,pos); } write(ans); //=========================================================== std::cerr << "Time:" << clock() - c1 << "ms" << std::endl; return 0; }
E.交换
map乱搞题,但就是不会Orz。。我们可以想到,最小的交换次数,其实就是每次都归位一个数。这时候,可能会想到直接数有多少个数位置不对就行,但是,这并不行,例如:1 4 3 2 5,4和2交换一次,就归位了两个数了,所以可以通过模拟过程来消除这种情况。注意,归位后还需要更新map的值!
#include <iostream> #include <map> #include <ctime> #include <vector> #include <climits> #include <algorithm> #include <random> #include <cstring> #include <cstdio> #include <map> #include <set> #include <bitset> #include <queue> #define inf 0x3f3f3f3f #define IOS ios_base::sync_with_stdio(0); cin.tie(0); #define rep(i, a, n) for(register int i = a; i <= n; ++ i) #define per(i, a, n) for(register int i = n; i >= a; -- i) //#define ONLINE_JUDGE using namespace std; typedef long long ll; const int mod=1e9+7; template<typename T>void write(T x) { if(x<0) { putchar('-'); x=-x; } if(x>9) { write(x/10); } putchar(x%10+'0'); } template<typename T> void read(T &x) { x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} ll lcm(ll a,ll b){return a/gcd(a,b)*b;}; ll ksm(ll a,ll n){//看是否要mod ll ans=1; while(n){ if(n&1) ans=(ans*a)%mod; a=a*a%mod; n>>=1; } return ans%mod; } //============================================================== const int maxn=100000+10; int n; int a[maxn]; int b[maxn]; int c[maxn]; int flag[maxn]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif clock_t c1 = clock(); //=========================================================== read(n); map<int,int> mark; rep(i,1,n){ read(a[i]); b[i]=a[i]; } sort(b+1,b+1+n); rep(i,1,n){ mark[a[i]]=i; } ll cnt=0; rep(i,1,n){ if(a[i]!=b[i]){ cnt++; int p1=i,p2=mark[b[i]]; swap(a[i],a[p2]); mark[a[i]]=i; mark[a[p2]]=p2; } } write(cnt); //=========================================================== std::cerr << "Time:" << clock() - c1 << "ms" << std::endl; return 0; }
另外,也可以运用一个找循环的做法做出来。
大佬博客:https://blog.csdn.net/lfb637/article/details/86653121
#include <iostream> #include <map> #include <ctime> #include <vector> #include <climits> #include <algorithm> #include <random> #include <cstring> #include <cstdio> #include <map> #include <set> #include <bitset> #include <queue> #define inf 0x3f3f3f3f #define IOS ios_base::sync_with_stdio(0); cin.tie(0); #define rep(i, a, n) for(register int i = a; i <= n; ++ i) #define per(i, a, n) for(register int i = n; i >= a; -- i) #define ONLINE_JUDGE using namespace std; typedef long long ll; const int mod=1e9+7; template<typename T>void write(T x) { if(x<0) { putchar('-'); x=-x; } if(x>9) { write(x/10); } putchar(x%10+'0'); } template<typename T> void read(T &x) { x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} ll lcm(ll a,ll b){return a/gcd(a,b)*b;}; ll ksm(ll a,ll n){//看是否要mod ll ans=1; while(n){ if(n&1) ans=(ans*a)%mod; a=a*a%mod; n>>=1; } return ans%mod; } //============================================================== const int maxn=100000+10; int n; int a[maxn]; int b[maxn]; int c[maxn]; int flag[maxn]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif clock_t c1 = clock(); //=========================================================== read(n); map<int,int> mark; rep(i,1,n){ read(a[i]); b[i]=a[i]; } sort(b+1,b+1+n); rep(i,1,n){ mark[b[i]]=i; } int flag[maxn]={0}; ll cnt=0; rep(i,1,n){ if(!flag[i]){ int j=i; while(!flag[j]){ flag[j]=1; j=mark[a[j]]; } cnt++; } } write(n-cnt); //=========================================================== std::cerr << "Time:" << clock() - c1 << "ms" << std::endl; return 0; }