您的位置:首页 > 大数据 > 人工智能

2015 Multi-University Training Contest 6 solutions BY ZJU(部分解题报告)

2015-08-07 14:22 766 查看
官方解题报告:http://bestcoder.hdu.edu.cn/blog/2015-multi-university-training-contest-6-solutions-by-zju/表示很难看。。。。orz1003题 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5355

Cake

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1138 Accepted Submission(s):152Special Judge[align=left]Problem Description[/align]There are m sodaand today is their birthday. The 1-stsoda has prepared n cakeswith size 1,2,…,n.Now 1-stsoda wants to divide the cakes into m partsso that the total size of each part is equal.Note that youcannot divide a whole cake into small pieces that is each cake must be completein the m parts.Each cake must belong to exact one of m parts.[align=left]Input[/align]There are multiple test cases. The first line of inputcontains an integer T,indicating the number of test cases. For each test case:The firstcontains two integers n and m (1≤n≤105,2≤m≤10),the number of cakes and the number of soda.It is guaranteed that the totalnumber of soda in the input doesn’t exceed 1000000. The number of test cases inthe input doesn’t exceed 1000.[align=left]Output[/align]For each test case, output "YES" (without the quotes)if it is possible, otherwise output "NO" in the first line.If it ispossible, then output m linesdenoting the m parts.The first number si of i-thline is the number of cakes in i-thpart. Then si numbersfollow denoting the size of cakes in i-thpart. If there are multiple solutions, print any of them.[align=left]Sample Input[/align]41 25 35 29 3[align=left]Sample Output[/align]NOYES1 52 1 42 2 3NOYES3 1 5 93 2 6 73 3 4 8[align=left]Source[/align]2015Multi-University Training Contest 6题意:n块蛋糕(大小1--n)分给m个人,要求每个人得到蛋糕大小总和相等
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 500000 + 10;
int ret[10][MAXN];
int vis[100], a[100];
int tot, tar;

bool dfs(int dep, int now, int u, int c)
{
if (now == 0)
{
int k = 0;
while (vis[k] != -1) ++ k;
vis[k] = c;
if (dfs(dep + 1, a[k], k + 1, c)) return true;
vis[k] = -1;
return false;
}
if (now == tar)
{
if (dep == tot) return true;
else return dfs(dep, 0, 0, c + 1);
}
for (int i = u; i < tot; ++ i)
{
if (vis[i] == -1 && now + a[i] <= tar)
{
vis[i] = c;
if (dfs(dep + 1, now + a[i], i + 1, c)) return true;
vis[i] = -1;
}
}
return false;
}

int main()
{
int T;
scanf("%d", &T);
for (int cas = 1; cas <= T; ++ cas)
{
int n, k;
scanf("%d%d", &n, &k);
//fprintf(stderr, "%d %d\n", n, k);
LL sum = (LL)n * (n + 1) / 2;
if (sum % k == 0 && n >= k * 2 - 1)
{
while (n >= 40)
{
for (int i = 0; i < k; ++ i) ret[i][++ ret[i][0]] = n - i;
for (int i = 0; i < k; ++ i) ret[i][++ ret[i][0]] = n - k * 2 + i + 1;
n -= k * 2;
}
tot = n;
tar = n * (n + 1) / 2 / k;
for (int i = 0; i < tot; ++ i) a[i] = tot - i;
for (int i = 0; i < tot; ++ i) vis[i] = -1;
dfs(0, 0, 0, 0);
for (int i = 0; i < tot; ++ i)
{
ret[vis[i]][++ ret[vis[i]][0]] = a[i];
}
for (int i = 0; i < k; ++ i)
{
printf("%d ", ret[i][0]);
for (int j = 1; j <= ret[i][0]; ++ j) printf(" %d", ret[i][j]);
puts("");
}
}
else puts("NO");
}
return 0;
}
1006题 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5358

First One

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072K (Java/Others)Total Submission(s): 757 Accepted Submission(s):230[align=left]Problem Description[/align]soda has an integer array a1,a2,…,an.Let S(i,j) bethe sum of ai,ai+1,…,aj.Now soda wants to know the value below:∑i=1n∑j=in(⌊log2S(i,j)⌋+1)×(i+j)Note:In this problem, you can consider log20 as0.[align=left]Input[/align]There are multiple test cases. The first line of inputcontains an integer T,indicating the number of test cases. For each test case:The first linecontains an integer n (1≤n≤105),the number of integers in the array.The next linecontains n integers a1,a2,…,an (0≤ai≤105).[align=left]Output[/align]For each test case, output the value.[align=left]Sample Input[/align]121 1[align=left]Sample Output[/align]12[align=left]Source[/align]2015Multi-University Training Contest 6题意:求思路:利用S(i,j)单调性, log2(S(i,j))+1= k=2^(k-1)<= S(i,j)<2^k考虑枚举log(sum(i,j)+1的值,记为k,然后统计(i+j)的和即可。对于每一个k,找到所有满足2^(k-1)<=sum(i,j)<=2^k-1的(i+j),k<=2*log2(10^5)<34转载请注明出处:寻找&星空の孩子
#include<stdio.h>
#include<math.h>
#include<algorithm>
#define LL long long
using namespace std;
LL num[100005];
LL sum[100005];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
LL n;
scanf("%lld",&n);
num[0]=sum[0]=0;
for(int i=1; i<=n; i++)
{
scanf("%lld",&num[i]);
sum[i]=sum[i-1]+num[i];
}
LL ans=0;
for(LL k=1; k<=34; k++)
{
LL l=1,r=0;//注意r的初始值在l的左边;因为存在1个值的情况!
LL KL=1LL<<(k-1);
if(k==1) KL--;
LL KR=1LL<<(k);
for(LL i=1; i<=n; i++)
{
l=max(i,l);//区间左边界
while(l<=n&&sum[l]-sum[i-1]<KL) l++;//确定左边界
r=max(l-1,r);//区间右边界,注意r在l前的时候从l-1开始
while(r+1<=n&&sum[r+1]-sum[i-1]>=KL&&sum[r+1]-sum[i-1]<KR) r++;//确定区间右边界
if(r<l) continue;
ans+=k*((i+l)+(i+r))*(r-l+1)/2;
}
}
printf("%lld\n",ans);
}
return 0;
}
1008题         链接:http://acm.hdu.edu.cn/showproblem.php?pid=5360

Hiking

Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 544 Accepted Submission(s):290Special Judge[align=left]Problem Description[/align]There are n sodaconveniently labeled by 1,2,…,n.beta, their best friends, wants to invite some soda to go hiking.The i-thsoda will go hiking if the total number of soda that go hiking except him is noless than li andno larger than ri.beta will follow the rules below to invite soda one by one:1. he selects asoda not invited before;2. he tells soda the number of soda who agree to gohiking by now;3. soda will agree or disagree according to the number hehears.Note: beta will always tell the truth and soda will agree if andonly if the number he hears is no less than li andno larger than ri,otherwise he will disagree. Once soda agrees to go hiking he will not regreteven if the final total number fails to meet some soda's will.Help betadesign an invitation order that the number of soda who agree to go hiking ismaximum.[align=left]Input[/align]There are multiple test cases. The first line of inputcontains an integer T,indicating the number of test cases. For each test case:The firstcontains an integer n (1≤n≤105),the number of soda. The second line constains n integers l1,l2,…,ln.The third line constains n integers r1,r2,…,rn. (0≤li≤ri≤n)Itis guaranteed that the total number of soda in the input doesn't exceed 1000000.The number of test cases in the input doesn't exceed 600.[align=left]Output[/align]For each test case, output the maximum number of soda.Then in the second line output a permutation of 1,2,…,n denotingthe invitation order. If there are multiple solutions, print any ofthem.[align=left]Sample Input[/align]484 1 3 2 2 1 0 35 3 6 4 2 1 7 683 3 2 0 5 0 3 64 5 2 7 7 6 7 682 2 3 3 3 0 0 27 4 3 6 3 2 2 585 6 5 3 3 1 2 46 7 7 6 5 4 3 5[align=left]Sample Output[/align]71 7 6 5 2 4 3 884 6 3 1 2 5 8 773 6 7 1 5 2 8 401 2 3 4 5 6 7 8[align=left]Source[/align]2015Multi-University Training Contest 6题意:问邀请的顺序,使得最终去的人最多,每个人有一个区间[l,r]的人数要求分析:用优先队列维护,按照r从小到大;不是很难注意细节。
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
using namespace std;
const int N = 100005;
struct nnn
{
int l,r,id;
}node
;
struct NNNN
{
int r,id;
friend bool operator<(NNNN aa,NNNN bb)
{
return aa.r>bb.r;
}
};

priority_queue<NNNN>q;
bool cmp1(nnn aa, nnn bb)
{
return aa.l<bb.l;
}
int id
;
bool vist
;
int main()
{
int T,n,ans;
NNNN now;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
ans=0;

/*for(int i=1; i<=n; i++)
printf("%d ",i);
printf("=id\n\n");*/
for(int i=0; i<n; i++)
{
scanf("%d",&node[i].l);
node[i].id=i+1;
}
for(int i=0; i<n; i++)
scanf("%d",&node[i].r);
sort(node,node+n,cmp1);
memset(vist,0,sizeof(vist));
int i=0;
while(i<n)
{
bool ff=0;
while(i<n&&ans>=node[i].l&&ans<=node[i].r)
{
now.r=node[i].r;
now.id=node[i].id;
q.push(now);
//printf("in = %d\n",now.id);
i++;
ff=1;
}
if(ff)i--;
while(!q.empty())
{
now=q.top(); q.pop();
if(now.r<ans)continue;
//printf("out = %d\n",now.id);
ans++;
id[ans]=now.id;
vist[now.id]=1;
if(node[i+1].l<=ans)
break;
}
i++;
}
while(!q.empty())
{
now=q.top(); q.pop();
if(now.r<ans)continue;
//printf("out = %d\n",now.id);
ans++;
id[ans]=now.id;
vist[now.id]=1;
}

bool fff=0;
printf("%d\n",ans);
for( i=1; i<=ans; i++)
if(i>1)
printf(" %d",id[i]);
else if(i==1)
printf("%d",id[i]);
if(ans)fff=1;
for( i=1; i<=n; i++)
if(vist[i]==0&&fff)
printf(" %d",i);
else if(vist[i]==0)
printf("%d",i),fff=1;
printf("\n");
}
}
1011题      链接:http://acm.hdu.edu.cn/showproblem.php?pid=5363

Key Set

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 420 Accepted Submission(s):275[align=left]Problem Description[/align]soda has a set S with n integers {1,2,…,n}.A set is called key set if the sum of integers in the set is an even number. Hewants to know how many nonempty subsets of S arekey set.[align=left]Input[/align]There are multiple test cases. The first line of inputcontains an integer T (1≤T≤105),indicating the number of test cases. For each test case:The first linecontains an integer n (1≤n≤109),the number of integers in the set.[align=left]Output[/align]For each test case, output the number of key setsmodulo 1000000007.[align=left]Sample Input[/align]41234[align=left]Sample Output[/align]0137[align=left]Source[/align]2015Multi-University Training Contest 6
 #include<stdio.h>#define LL long long#define mod 1000000007LL ppow(LL a,LL b){LL c=1;while(b){if(b&1) c=c*a%mod;b>>=1;a=a*a%mod;}return c;}int main(){int T;LL n;scanf("%d",&T);while(T--){scanf("%lld",&n);printf("%lld\n",ppow(2,n-1)-1);}return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: