17-09-10模拟赛

T1:考虑对每一个数位做前缀和,将前缀和中最小的一位找出并将所有位减去该值,查询时每一位值相同时即为解。

用hash存储数据,注意第0个数的前缀和也应当加入hash中(使第一个数能被取到)。

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define inf 0x7fffffff
 5 #define MN 100010
 6 #define mod 100007
 7 #define MK 33
 8 using namespace std;
 9 inline int in(){
10     int x=0;bool f=0; char c;
11     for (;(c=getchar())<'0'||c>'9';f=c=='-');
12     for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
13     return f?-x:x;
14 }
15 struct edge{
16     int next,pos;
17 }e[MN];
18 int head[MN],sum[MN][MK],mn,cnt=0,ct,n,m,x,ans=0;
19 inline void ins(int hs,int x){
20     e[++cnt].pos=x;e[cnt].next=head[hs];head[hs]=cnt;
21 }
22 inline bool ghs(int hs,int u){
23     for (int i=head[hs];i;i=e[i].next){
24         int v=e[i].pos;bool f=0;
25         for (int j=1;j<=m;++j)
26         if(sum[u][j]!=sum[v][j]) {f=1;break;}
27         if (!f) {ans=max(ans,u-v);return 1;}
28     }return 0;
29 }
30 inline void has(int u){
31     int hs=0;
32     for (int i=1;i<=m;++i) hs=(hs+sum[u][i])%mod;
33     if (!ghs(hs,u)) ins(hs,u); 
34 }
35 int main()
36 {
37     n=in();m=in();has(0);
38     for (int i=1;i<=n;++i){
39         x=in();mn=inf;ct=0;
40         for (int j=1;j<=m;++j) sum[i][j]=sum[i-1][j]+(x&1),x>>=1;
41         for (int j=1;j<=m;++j) mn=min(sum[i][j],mn);
42         for (int j=1;j<=m;++j) sum[i][j]-=mn;has(i);
43     }printf("%d",ans);return 0;
44 }

T2:二分答案。参考NOIP2015 取石子。

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 inline int in(){
 6     int x=0;bool f=0; char c;
 7     for (;(c=getchar())<'0'||c>'9';f=c=='-');
 8     for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
 9     return f?-x:x;
10 }
11 int a[50005],n,m,k,l,r,ans=0;
12 inline bool check(int x){
13     int cur=0,cnt=0;
14     for (int i=1;i<=m;++i){
15         if (a[i]-cur-1<x||n-a[i]-1<x) ++cnt;else cur=a[i];
16     }return (cnt<=k);
17 }
18 int main()
19 {
20     n=in();m=in();k=in();
21     for (int i=1;i<=m;++i) a[i]=in();sort(a+1,a+m+1);
22     l=0;r=n-1;while(l<=r){
23         int mid=(l+r)>>1;
24         if (check(mid)) ans=mid,l=mid+1;else r=mid-1;
25     }printf("%d",ans);return 0;
26 }

T3:考虑将问题按时间从小到大排序。

对于第i个问题,如果在它之前的任务少于ti个,那么把任务加入。

否则比较该任务与先前任务中价值最小的任务的价值,完成价值较大的任务。

用堆维护任务价值。时间复杂度O(n log n).

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 #define MN 100005
 6 #define ll long long
 7 using namespace std;
 8 inline int in(){
 9     int x=0;bool f=0; char c;
10     for (;(c=getchar())<'0'||c>'9';f=c=='-');
11     for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
12     return f?-x:x;
13 }
14 struct prob{
15     int w,t;
16 }a[MN];
17 priority_queue<int,vector<int>,greater<int> >q;
18 bool vis[MN];
19 int n;
20 ll ans=0ll;
21 inline bool cmp(prob a,prob b){return a.t<b.t;}
22 int main()
23 {
24     n=in();for (int i=1;i<=n;++i) a[i].t=in(),a[i].w=in();
25     sort(a+1,a+n+1,cmp);int cnt=0;
26     for (int i=1;i<=n;++i){
27         if (cnt<a[i].t) q.push(a[i].w),ans+=1ll*a[i].w,++cnt;
28         else{
29             int u=q.top();
30             if (a[i].w>u) q.pop(),q.push(a[i].w),ans+=1ll*(a[i].w-u);
31         }
32     }printf("%lld",ans);return 0;
33 }

T4:最小生成树。将每个点搭建发电机的费用看作向0号点连边的费用即可。

用Prim算法求得MST,时间效率O(n2).

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define MN 304
 5 using namespace std;
 6 inline int in(){
 7     int x=0;bool f=0; char c;
 8     for (;(c=getchar())<'0'||c>'9';f=c=='-');
 9     for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
10     return f?-x:x;
11 }
12 int a[MN][MN],c[MN],n,ans=0;
13 bool vis[MN];
14 int main()
15 {
16     n=in();for (int i=1;i<=n;++i) a[0][i]=a[i][0]=in();
17     for (int i=1;i<=n;++i)
18     for (int j=1;j<=n;++j) a[i][j]=in();
19     memset(c,0x3f,sizeof(c));c[0]=0;
20     while (1){
21         int v=-1;for (int j=0;j<=n;++j)
22         if (!vis[j]&&(v==-1||c[j]<c[v])) v=j;
23         if (v==-1) break;vis[v]=1;ans+=c[v];
24         for (int j=0;j<=n;++j) if (a[v][j])c[j]=min(c[j],a[v][j]);
25     }printf("%d",ans);return 0;
26 }

 

posted on 2017-09-11 17:01  whz2002  阅读(105)  评论(0编辑  收藏  举报