A. Alarm Clock
按照题意模拟就好了
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAX_N=1e7+10; 4 const int N=2e5+60; 5 typedef unsigned long long ULL; 6 typedef long long ll; 7 #define form(i,n) for(int i=1;i<=n;i++) 8 #define forn(i,n) for(int i=0;i<n;i++) 9 #define mst(a) memset(a,0,sizeof(a)) 10 #define P pair<int,int> 11 #define wh(T) while(T--) 12 int main(){ 13 ios::sync_with_stdio(0); 14 ll T,a,b,c,d; 15 cin>>T; 16 while (T--){ 17 cin>>a>>b>>c>>d; 18 if(b>=a){ 19 cout<<b<<endl; 20 continue; 21 } 22 if(c<=d){ 23 cout<<-1<<endl; 24 continue; 25 } 26 if((a-b)%(c-d)==0) 27 cout<<(a-b)/(c-d)*c+b<<endl; 28 else 29 cout<<((a-b)/(c-d)+1)*c+b<<endl; 30 } 31 }
B. Ternary String
找到最短的包含123的连续子串,用v[123]来表示123的位置,ans=min(ans,当前位置-123中第一个数出现的最后位置+1)
#include <bits/stdc++.h> using namespace std; const int MAX_N=1e7+10; const int N=2e5+60; typedef unsigned long long ULL; typedef long long ll; #define form(i,n) for(int i=1;i<=n;i++) #define forn(i,n) for(int i=0;i<n;i++) #define mst(a) memset(a,0,sizeof(a)) #define P pair<int,int> #define wh(T) while(T--) string s; const int inf=3e7; int main(){ ios::sync_with_stdio(0); ll T; cin>>T; while (T--){ cin>>s; int v[3],ans=inf; v[0]=v[1]=v[2]=-1; int len=s.length(); forn(i,len){ v[s[i]-'1']=i; if(v[0]!=-1&&v[1]!=-1&&v[2]!=-1){ ans=min(ans,i-min(v[0],min(v[1],v[2]))+1); } } if(ans==inf)ans=0; cout<<ans<<endl; } }
为偶数时显然多变形有四条边和正方形是紧贴的,然后连接对角,已知内角a和对边=1,高中几何知识可做
#include <bits/stdc++.h> using namespace std; const int MAX_N=1e7+10; const int N=2e5+60; typedef unsigned long long ULL; typedef long long ll; #define form(i,n) for(int i=1;i<=n;i++) #define forn(i,n) for(int i=0;i<n;i++) #define mst(a) memset(a,0,sizeof(a)) #define P pair<int,int> #define wh(T) while(T--) string s; const int inf=3e7; const double PI=acos(-1); int main(){ int T; scanf("%d",&T); wh(T){ double n; double angle,ans; scanf("%lf",&n); angle=PI/n; ans=1.0/tan(angle/2.0); printf("%.7f ",ans); } }
C2Not So Simple Polygon Embedding
这时候我们发现如果是角顶着正方形的边的话正方形不是最小,这时候让多变形倾斜一点并缩小正方形直到多变形有四个角顶住正方形为止,我们需要知道的是他比原来倾斜了几度。连接各对角线后,会出现很多有一个角在中心的全等三角形,称这个角为a,由对称性可知如果倾斜的角度超过了pi/(n*2),既超过了a的一半,则和反方向倾斜pi-a一样,所以只要考虑倾斜角度在0到a/2,画了一个六边形后发现倾斜了1/4a达到 最大,大胆猜测是倾斜1/4a为正解,比对样例可以,提交可以
#include <bits/stdc++.h> using namespace std; const int MAX_N=1e7+10; const int N=2e5+60; typedef unsigned long long ULL; typedef long long ll; #define form(i,n) for(int i=1;i<=n;i++) #define forn(i,n) for(int i=0;i<n;i++) #define mst(a) memset(a,0,sizeof(a)) #define P pair<int,int> #define wh(T) while(T--) string s; const int inf=3e7; const double PI=acos(-1); int main(){ int T; scanf("%d",&T); wh(T){ double n; double angle,ans; scanf("%lf",&n); angle=PI/n; ans=1.0/sin(angle/2.0)*cos(angle/4); printf("%.7f ",ans); } }
给1e6得数并以字典序排列
之后继续插入数,或者删除指定位置数,操作数不超过1e6
也就是说,操作数有1e6的话操作过程最多log,树状数组可以实现log级别的删除添加状态,
具体:插入数a时,对应add(a,1),删除数时假设指定位置b删除,所以二分查找对应位置前缀和为b的第一次出现的地方,然后add(所在位置的数,-1)
总共复杂度为nlognlog,1.5秒勉强可过
这道题也可以用线段树做,线段树相对代码的复杂度高,能用树状数组就树状数组吧
#include <bits/stdc++.h> using namespace std; typedef unsigned long long ULL; typedef long long ll; #define form(i,n) for(int i=1;i<=n;i++) #define forn(i,n) for(int i=0;i<n;i++) #define mst(a) memset(a,0,sizeof(a)) #define P pair<int,int> #define wh(T) while(T--) const int MAX_N=1e7+10; const int N=1e6+90; const int inf=1e8; int c[N],n,m,MAX=1e6; int lowbit(int x){ return x&-x; } void add(int x,int y){ while (x<=MAX){ c[x]+=y; x+=lowbit(x); } } int query(int x){ int res=0; while (x){ res+=c[x]; x-=lowbit(x); } return res; } int main() { ios::sync_with_stdio(0); cin>>n>>m; int t; form(i,n){ cin>>t; add(t,1); } // cout<<t<<"ss"<<c[1]<<endl; form(i,m){ cin>>t; int l=1,r=MAX; if(t>0) { add(t,1); } else{ while (l < r) { int mid = (l + r) >> 1; int tmp = query(mid); if (tmp < abs(t)) l = mid + 1; else if (tmp >= abs(t)) r = mid; } add(l,-1); } // cout<<l<<"ss"<<c[1]<<endl; } if(query(1e6)==0)cout<<0; else{ int l=1,r=MAX; while (l<r){ int mid =(l+r)>>1; int tmp=query(mid); if(tmp<1) l=mid+1; else if(tmp>=1) r=mid; } cout<<l; } }