正睿 2018 普及组5连测 Day2

前言:这一周算比较良心吧...(小伙速度还是要提快一点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\n",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 } 

细致...读题清楚...速度...

 

posted @ 2018-09-22 17:29  degage  阅读(314)  评论(0编辑  收藏  举报