前言:这一周算比较良心吧...(小伙速度还是要提快一点a.....)
T1:
一个比较简单的模拟题,所以才更要注重细节啊......
需要注意的一点,求两个矩形相交的面积
设矩形1左下角点坐标为(x1,y1)右上角点坐标为(x2,y2)
设矩形2左下角点坐标为(x3,y3)右上角点坐标为(x4,y4)
记minx=max(x1,x3),miny=max(y1,y3),maxx=min(x2,x4),maxy=min(y2,y4)
矩形1,2相交的条件是minx<maxx并且miny<maxy
满足则相交面积为(maxx-minx)*(maxy-miny);
其他就没什么了,模拟一定要注意细节,稳住心态,忌焦忌躁,可以现在纸上列出需要执行的事项,一项项执行,心态心态心态!
上代码:
1 #include<bits/stdc++.h> 2 #define maxn 2005 3 typedef long long ll; 4 using namespace std; 5 struct node{ 6 ll p,x,y; 7 ll w; 8 ll h; 9 int id; 10 }nd[maxn]; 11 bool cmp(node a,node b){ 12 return a.p>b.p; 13 } 14 bool vis[maxn]; 15 int n,a,st[maxn],top=0,a1,a2,a3,a4; 16 ll check(ll x,ll y,ll w,ll h,ll xx,ll yy,ll ww,ll hh){ 17 ll s; 18 ll minx=max(x-w,xx-ww); 19 ll miny=max(y-h,yy-hh); 20 ll maxx=min(x+w,xx+ww); 21 ll maxy=min(y+h,yy+hh); 22 if(minx<maxx&&miny<maxy) s=(maxx-minx)*(maxy-miny);//即使为负也没什么关系 23 else s=0; 24 25 return s; 26 } 27 void init(){ 28 scanf("%d",&n); 29 int pos=0; 30 int tt=n;//防O2优化 31 for(int i=1;i<=tt;i++){ 32 scanf("%lld",&a); 33 int t=a/100000; 34 if(t<6){ 35 scanf("%d%d%d%d",&a1,&a2,&a3,&a4); 36 continue; 37 } 38 ++pos; 39 scanf("%lld%lld%lld%lld",&nd[pos].x,&nd[pos].y,&nd[pos].w,&nd[pos].h);//注意这里是半长半高 40 nd[pos].p=a; 41 nd[pos].id=i; 42 } 43 int poss=1; 44 int cnt=pos; 45 sort(nd+1,nd+pos+1,cmp); 46 while(cnt){ 47 cnt--; 48 while(vis[nd[poss].id]&&poss<=pos) poss++; 49 vis[nd[poss].id]=1; 50 st[++top]=nd[poss].id; 51 ll x=nd[poss].x,y=nd[poss].y,w=nd[poss].w,h=nd[poss].h; 52 poss++; 53 for(int i=poss;i<=pos;i++){ 54 if(!vis[nd[i].id]){ 55 ll xx=nd[i].x,yy=nd[i].y,ww=nd[i].w,hh=nd[i].h; 56 ll cd=check(x,y,w,h,xx,yy,ww,hh); 57 ll s=(w*2)*(h*2),ss=(ww*2)*(hh*2); 58 ll bin=s+ss-cd,jiao=cd; 59 if((2*jiao)>bin){ 60 vis[nd[i].id]=1;cnt--; 61 } 62 } 63 } 64 } 65 sort(st+1,st+top+1); 66 for(int i=1;i<=top;i++) printf("%d ",st[i]); 67 } 68 int main(){ 69 init(); 70 71 return 0; 72 }
T2:
比较简单的dp题(考试时人工记录了每个字母对应的情况,可以冷静下用电脑计入快一些)
设状态dp[i][0/1]表示前i个电码是否以'Z'结尾表示的种数
为了使不出现‘ZR’两个字符,只在匹配到R的时候不计入dp[i-1][1]即可
转移方程:if(j==26) dp[pos-1][1]=(dp[pos-1][1]+dp[i-1][0]+dp[i-1][1])%mod;
else if(j!=18) dp[pos-1][0]=(dp[pos-1][0]+dp[i-1][0]+dp[i-1][1])%mod;
else dp[pos-1][0]=(dp[pos-1][0]+dp[i-1][0])%mod;//注:pos-1为当前匹配到的位置
上代码:
1 #include<bits/stdc++.h> 2 #define maxn 1000005 3 using namespace std; 4 typedef long long ll; 5 const ll mod=1e9+7; 6 ll dp[maxn][2]; 7 char mp[30][7]; 8 char s[maxn]; 9 void ready(){ 10 mp[1][1]='0',mp[1][2]='1',mp[2][1]='1',mp[2][2]='0',mp[2][3]='0',mp[2][4]='0',mp[3][1]='1',mp[3][2]='0',mp[3][3]='1',mp[3][4]='0',mp[4][1]='1',mp[4][2]='0',mp[4][3]='0',mp[5][1]='0',mp[6][1]='0',mp[6][2]='0',mp[6][3]='1',mp[6][4]='0',mp[7][1]='1',mp[7][2]='1',mp[7][3]='0',mp[8][1]='0',mp[8][2]='0',mp[8][3]='0',mp[8][4]='0',mp[9][1]='0',mp[9][2]='0',mp[10][1]='0',mp[10][2]='1',mp[10][3]='1',mp[10][4]='1',mp[11][1]='1'; 11 mp[11][2]='0',mp[11][3]='1',mp[12][1]='0',mp[12][2]='1',mp[12][3]='0',mp[12][4]='0',mp[13][1]='1',mp[13][2]='1',mp[14][1]='1',mp[14][2]='0',mp[15][1]='1',mp[15][2]='1',mp[15][3]='1',mp[16][1]='0',mp[16][2]='1',mp[16][3]='1',mp[16][4]='0',mp[17][1]='1',mp[17][2]='1',mp[17][3]='0',mp[17][4]='1',mp[18][1]='0',mp[18][2]='1',mp[18][3]='0',mp[19][1]='0',mp[19][2]='0',mp[19][3]='0',mp[20][1]='1',mp[21][1]='0',mp[21][2]='0',mp[21][3]='1',mp[22][1]='0',mp[22][2]='0',mp[22][3]='0',mp[22][4]='1',mp[23][1]='0',mp[23][2]='1',mp[23][3]='1',mp[24][1]='1',mp[24][2]='0',mp[24][3]='0',mp[24][4]='1',mp[25][1]='1',mp[25][2]='0',mp[25][3]='1',mp[25][4]='1',mp[26][1]='1',mp[26][2]='1',mp[26][3]='0',mp[26][4]='0'; 12 } 13 void dpp(){ 14 int len=strlen(s+1); 15 dp[0][0]=1;int pos; 16 for(int i=1;i<=len;i++){ 17 for(int j=1;j<=26;j++){ 18 pos=i; 19 bool ok=true; 20 while(mp[j][pos-i+1]){ 21 if(mp[j][pos-i+1]!=s[pos]||pos>len){ 22 ok=false;break; 23 } 24 pos++; 25 } 26 if(ok){ 27 if(j==26) dp[pos-1][1]=(dp[pos-1][1]+dp[i-1][0]+dp[i-1][1])%mod; 28 else if(j!=18) dp[pos-1][0]=(dp[pos-1][0]+dp[i-1][0]+dp[i-1][1])%mod; 29 else dp[pos-1][0]=(dp[pos-1][0]+dp[i-1][0])%mod; 30 } 31 } 32 } 33 printf("%lld",(dp[len][0]+dp[len][1])%mod); 34 } 35 int main(){ 36 ready(); 37 scanf("%s",s+1); 38 dpp(); 39 40 return 0; 41 }
T3:
emmmmmmm这道题海星,首先必须意识到符号相同的几个单位之间可以使用交换律和结合律,而根据题目,可知几个单位合并的最小代价需要贪心,即合并果子,这里用堆实现即可。所以dfs一遍,遇到不同符号的就得计算。细心实现即可。上代码:
1 //并行计算 2 #include<bits/stdc++.h> 3 #define maxn 500005 4 using namespace std; 5 typedef long long ll; 6 char opp[maxn]; 7 int op[maxn],fa[maxn*2],n,x,y; 8 ll wj,wc; 9 struct eage{ 10 int to,next; 11 }e[maxn<<1]; 12 int np=0,first[maxn]; 13 void add(int u,int v){ 14 e[++np]=(eage){v,first[u]}; 15 first[u]=np; 16 } 17 ll st[maxn*2]; 18 int top=0; 19 struct noded{ 20 ll w; 21 friend bool operator <(noded a,noded b){ 22 return a.w>b.w; 23 } 24 }; 25 void dfs(int now,int pre){ 26 int topp=top; 27 if(now>=n){st[++top]=0;return;} 28 29 for(int p=first[now];p;p=e[p].next){ 30 int j=e[p].to; 31 dfs(j,op[now]); 32 } 33 34 if((op[now]^pre)||pre==-1){ 35 priority_queue<noded>q; 36 while(top!=topp) q.push((noded){st[top--]}); 37 while(23333){ 38 noded i=q.top();q.pop(); 39 if(q.empty()){ 40 st[++top]=i.w; 41 break; 42 } 43 noded ii=q.top();q.pop(); 44 ll ww=max(ii.w,i.w)+(op[now]==1?wj:wc); 45 q.push((noded){ww}); 46 } 47 } 48 49 } 50 void init(){ 51 scanf("%d%lld%lld",&n,&wj,&wc); 52 scanf("%s",opp); 53 for(int i=1;i<=n-1;i++) op[i]=(opp[i-1]=='+'?1:0);//标记 54 for(int i=1;i<=2*n-2;i++){ 55 scanf("%d%d",&x,&y); 56 add(x,y); 57 fa[y]=x; 58 } 59 int root; 60 for(int i=1;i<=2*n-1;i++) if(fa[i]==0){root=i;break;} 61 62 dfs(root,-1); 63 printf("%lld",st[top]); 64 } 65 int main(){ 66 init(); 67 68 return 0; 69 }
T4:
这道题比较复杂a....要推很多式子,注意细节....
首先想到应该是二分,然后主要check函数:如果我们知道其他人票数v·,以及席位个数x那么(这个不能编辑公式aqwq)可以根据题意解一个不等式得到x的最小值然后只要满足∑xi<=m-mid即可。
令 f(i,j) 表考虑了前 i 个政党(第1个除外)留给下一个政党还剩 j 的票(就是 ai 中分配给第 i + 1 个政党 j 票),前 i 个政党的 xi 之和最小是多少。
随后观察数据范围,将j表示还剩的票与选得的位置交换(很Nice的思路)令f(i,j)表考虑了前 i 个政党(第1个除外)的 xi 之和是j,留给下一
个政党 i + 1 的票数最少是多少。 //这里运用贪心,下一个最少则席位最少。
这个时候对于每一个i,会获得从前面来的f票,此刻为满足只占x个席位可通过不等式求出再多拿票的最大值(这样剩的票就少)枚举每个xi就行。
上代码:
1 //席位选举 2 #include<bits/stdc++.h> 3 #define maxn 55 4 #define maxm 505 5 using namespace std; 6 typedef long long ll; 7 int n,m,a[maxn],v[maxn],dp[maxn][maxm]; 8 bool check(int mid){ 9 memset(dp,0x3f,sizeof(dp)); 10 dp[1][0]=0; 11 for(int i=1;i<n-1;i++){//前i个选了j个席位 12 for(int j=0;j<=m;j++){ 13 for(int k=0;j+k<=m;k++){ 14 if (v[1]*(k+1)/mid-v[i+1]-dp[i][j]>=0) 15 dp[i+1][j+k]=min(dp[i+1][j+k],max(0,a[i+1]-(v[1]*(k+1)/mid-v[i+1]-dp[i][j]))); 16 } 17 } 18 } 19 ll ans=1LL<<60; 20 for (int j=0;j<=m;j++){ 21 int vi=v[n]+dp[n-1][j]; 22 ll s=max(0LL,((ll)mid*vi-1)/v[1]); 23 ans=min(ans,j+s); 24 } 25 return ans<=m-mid; 26 } 27 void run(){ 28 int L=0,R=m+1,mid; 29 while (L+1<R) 30 if (check(mid=(L+R)>>1)) 31 L=mid; 32 else 33 R=mid; 34 printf("%d ",L); 35 } 36 void init(){ 37 scanf("%d%d",&n,&m); 38 for(int i=1;i<=n;i++) scanf("%d",&v[i]); 39 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 40 v[1]=v[1]+a[1]+a[n]; 41 run(); 42 } 43 int main(){ 44 init(); 45 46 return 0; 47 }
细致...读题清楚...速度...