码迷,mamicode.com
首页 > 其他好文 > 详细

2017 Multi-University Training 1 解题报告

时间:2017-07-26 18:06:28      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:this   row   several   long   所有路径   view   选择   计算   preview   

Add More Zero

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2245    Accepted Submission(s): 1053


Problem Description

There is a youngster known for amateur propositions concerning several mathematical hard problems.

Nowadays, he is preparing a thought-provoking problem on a specific type of supercomputer which has ability to support calculations of integers between 0技术分享 and (2技术分享m技术分享?1)技术分享 (inclusive).

As a young man born with ten fingers, he loves the powers of 10技术分享 so much, which results in his eccentricity that he always ranges integers he would like to use from 1技术分享 to 10技术分享k技术分享技术分享 (inclusive).

For the sake of processing, all integers he would use possibly in this interesting problem ought to be as computable as this supercomputer could.

Given the positive integer m技术分享 , your task is to determine maximum possible integer k技术分享 that is suitable for the specific supercomputer.

 

 

Input

The input contains multiple test cases. Each test case in one line contains only one positive integer m技术分享 , satisfying 1m≤$10^5$ .

 

 

Output

For each test case, output "Case #x技术分享 : y技术分享 " in one line (without quotes), where x技术分享 indicates the case number starting from 1技术分享 and y技术分享 denotes the answer of corresponding case.

 

 

Sample Input

1 64

 

 

Sample Output

Case #1: 0 Case #2: 19


 

技术分享

 

 

技术分享
 1 #include<bits/stdc++.h>
 2 #define clr(x) memset(x,0,sizeof(x))
 3 using namespace std;
 4 int main()
 5 {
 6     int m;
 7     int t = 1;
 8     while(cin >> m) {
 9 
10         cout << "Case #" << t ++ << ": " << (int)(m*0.30102999566)<< "\n";
11     }
12     return 0;
13 }
View Code

 

 

Balala Power!

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 4809    Accepted Submission(s): 387


Problem Description

技术分享


Talented Mr.Tang has n技术分享 strings consisting of only lower case characters. He wants to charge them with Balala Power (he could change each character ranged from a to z into each number ranged from 0 to 25, but each two different characters should not be changed into the same number) so that he could calculate the sum of these strings as integers in base 26技术分享 hilariously.

Mr.Tang wants you to maximize the summation. Notice that no string in this problem could have leading zeros except for string "0". It is guaranteed that at least one character does not appear at the beginning of any string.

The summation may be quite large, so you should output it in modulo 10技术分享9技术分享+7技术分享 .

 

 

Input

The input contains multiple test cases.

For each test case, the first line contains one positive integers n技术分享 , the number of strings. (1n100000)技术分享

Each of the next n技术分享 lines contains a string s技术分享i技术分享技术分享 consisting of only lower case letters. (1|s技术分享i技术分享|100000,|s技术分享i技术分享|10技术分享6技术分享)技术分享

 

 

Output

For each test case, output "Case #x技术分享 : y技术分享 " in one line (without quotes), where x技术分享 indicates the case number starting from 1技术分享 and y技术分享 denotes the answer of corresponding case.

 

 

Sample Input

1 a 2 aa bb 3 a ba abc

 

 

Sample Output

Case #1: 25 Case #2: 1323 Case #3: 18221


 
第二题的话,我们对于每种字母,统计他在每个字符串各位上出现的次数,并把他们组成一个26进制数(统计完进位变成26进制数),每个字母的这个26进制数乘给该字母的赋值即为该字母对答案的贡献。显而易见,对字母按照这个26进制数(即权值)拍个序,从大到小给他们赋值,则能保证答案是最大的。但是由于不能出现前导0,所以对于长度大于1的字符串,他的首字母不能为0,所以首先0应选择一个没有出现在字符串首字母的字母并且这些字母中权值最小的先赋值,然后接下来最小的赋值到最大的赋值依次按照字母的权值大小给其赋值。最后将该权值和对应赋值相乘然后全部相加即为答案。
技术分享
 1 #include <bits/stdc++.h>
 2 #define clr(x) memset(x,0,sizeof(x))
 3 #define mod 1000000007
 4 #define LL long long
 5 using namespace std;
 6 char ss[100020];
 7 int n,m,k,l,t,minc,len;
 8 int charc[50][100020];
 9 bool firsted[200];
10 int inf[200];
11 bool comp(int a,int b)
12 {
13     for(int i=m;i>=0;i--)
14         if(charc[a-a][i]!=charc[b-a][i])
15             return charc[a-a][i]>charc[b-a][i];
16     return 0;
17 }
18 int max(int a,int b)
19 {
20     return a>b?a:b;
21 }
22 int main()
23 {
24     int T,kase=0;
25     LL ans,mul;
26     while(scanf("%d",&n)!=EOF)
27     {
28         m=0;
29         clr(firsted);
30         clr(charc);
31         printf("Case #%d: ",++kase);
32         for(int i=1;i<=n;i++)
33         {
34             scanf("%s",ss);
35             len=strlen(ss);
36             if(len>0) firsted[ss[0]]=1;
37             reverse(ss,ss+len);
38             for(int j=0;j<len;j++)
39                 charc[ss[j]-a][j]++;
40             m=max(m,len);
41         }
42         for(int i=a;i<=z;i++)
43         {
44 //            cout<<i<<":";
45             for(int j=0;j<m;j++)
46             {
47                 if(charc[i-a][j]>25)
48                 {
49                     charc[i-a][j+1]+=charc[i-a][j]/26;
50                     charc[i-a][j]%=26;
51                 }
52 //                cout<<" "<<charc[i-‘a‘][j];
53             }
54             while(charc[i-a][m]>25)
55             {
56                     charc[i-a][m+1]+=charc[i-a][m]/26;
57                     charc[i-a][m]%=26;
58                     m++;
59  //                   cout<<" "<<charc[i-‘a‘][m];
60             }
61             if(charc[i-a][m]>0)
62                 m++;
63  //           cout<<endl;
64         }
65         clr(inf);
66         ans=0;
67         for(int i=0;i<=25;i++)
68         {
69             for(int j=a;j<=z;j++)
70                 if((i==0 && firsted[j]==0) || (i!=0 && inf[j-a]==0))
71                 {
72                     minc=j;
73                     break;
74                 }
75             for(int j=a;j<=z;j++)
76                 if((i==0 && firsted[j]==0) || (i!=0 && inf[j-a]==0))
77                     if(!comp(j,minc))
78                         minc=j;
79             mul=1;
80             for(int j=0;j<=m;j++)
81             {
82                 ans=(ans+(LL)charc[minc-a][j]*mul*(LL)i)%mod;
83                 mul=(mul*26)%mod;
84             }
85             inf[minc-a]=1;
86 //            cout<<ans<<" "<<maxc<<endl;
87         }
88         printf("%lld\n",ans);
89     }
90     return 0;
91 }
View Code

 

Colorful Tree

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 392    Accepted Submission(s): 68


Problem Description

There is a tree with n技术分享 nodes, each of which has a type of color represented by an integer, where the color of node i技术分享 is c技术分享i技术分享技术分享 .

The path between each two different nodes is unique, of which we define the value as the number of different colors appearing in it.

Calculate the sum of values of all paths on the tree that has n(n?1)技术分享2技术分享技术分享技术分享 paths in total.

 

 

Input

The input contains multiple test cases.

For each test case, the first line contains one positive integers n技术分享 , indicating the number of node. (2n200000)技术分享

Next line contains n技术分享 integers where the i技术分享 -th integer represents c技术分享i技术分享技术分享 , the color of node i技术分享 . (1c技术分享i技术分享n)技术分享

Each of the next n?1技术分享 lines contains two positive integers x,y技术分享 (1x,yn,xy)技术分享 , meaning an edge between node x技术分享 and node y技术分享 .

It is guaranteed that these edges form a tree.

 

 

Output

For each test case, output "Case #x技术分享 : y技术分享 " in one line (without quotes), where x技术分享 indicates the case number starting from 1技术分享 and y技术分享 denotes the answer of corresponding case.

 

 

Sample Input

3 1 2 1 1 2 2 3 6 1 2 1 3 2 1 1 2 1 3 2 4 2 5 3 6

 

 

Sample Output

Case #1: 6 Case #2: 29


该题应该按照颜色来求解,而不是点和路径来求解。每种颜色对答案的贡献为所有经过该颜色的点的路径数,也就是所有的路径数减去没有经过该颜色的点的路径数。那么求解量转化成该颜色的点的路径数之后,对于每个颜色我们接下来则是找树上没有经过该颜色的块,统计块内的点的数量,这些点都是互相可达且不经过该颜色,那么块内不经过该颜色的路径数就是块中点数ki*(ki-1)/2。那么很浅显的一个思路就是对于每个颜色都用dfs求解出不经过颜色的块然后用总的路径数减去每个块内的路径数,即为每个颜色的贡献。可是这个时间复杂度会很高,那能不能在一次dfs内解决呢?我们可以发觉在对每个颜色的点的dfs中,我们只有dfs到该颜色的点才有操作,去计算块内点的数量。那么一遍dfs的话,对于每个点它对应的颜色都应该有相应的操作,这样思路就显而易见了。我们在一次dfs中可以统计对于每个点子树中节点的数量,然后我们对于每个颜色都设置一个栈来存储该颜色的点的编号。当到dfs到某个点时,我们将该点的编号入相应颜色的栈继续向下dfs。然后回到该点的时候将该颜色在该点之后入栈的点全部都pop出来,然后该颜色的块的点的数量即为该点子树的点的数量减去pop出来的点的子树的数量,计算下路径数加入答案中作为没有经过该颜色的点的路径数的贡献。最后拿每个颜色的所有路径数的和,减去这个没有经过每个颜色的点的路径数的总和即为答案。
把g++改成c++就不超空间过了,这个东西卡了我很久不知道原理。
技术分享
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<stack>
 5 #include<vector>
 6 #define clr(x) memset(x,0,sizeof(x))
 7 #define clr_1(x) memset(x,-1,sizeof(x))
 8 #define LL long long
 9 using namespace std;
10 int head[200005],cnt,ncnt,dif,col[200005];
11 LL ans;
12 int n,m,k,t,s,l;
13 struct edg
14 {
15     int next,to;
16 }edge[400005];
17 void addedge(int u,int v)
18 {
19     edge[++cnt].next=head[u];
20     edge[cnt].to=v;
21     head[u]=cnt;
22     return ;
23 }
24 int some[200005];
25 stack<int> sta[200005];
26 void dfs(int u,int pred)
27 {
28     some[u]=1;
29     sta[col[u]].push(u);
30     for(int i=head[u];i!=-1;i=edge[i].next)
31     {
32         if(edge[i].to!=pred)
33         {
34             dfs(edge[i].to,u);
35             some[u]+=some[edge[i].to];
36             dif=some[edge[i].to];
37             while(sta[col[u]].top()!=u)
38             {
39                 dif-=some[sta[col[u]].top()];
40                 sta[col[u]].pop();
41             }
42             ans+=(LL)dif*(dif-1)/2;
43         }
44     }
45     return ;
46 }
47 int main()
48 {
49     int kase=0,u,v,diff,p;
50     while(scanf("%d",&n)!=EOF)
51     {
52         for(int i=1;i<=n;i++)
53             while(!sta[i].empty())
54                 sta[i].pop();
55         printf("Case #%d: ",++kase);
56         clr_1(head);
57         cnt=ncnt=0;
58         for(int i=1;i<=n;i++)
59             scanf("%d",&col[i]);
60         for(int i=1;i<n;i++)
61         {
62             scanf("%d%d",&u,&v);
63             addedge(u,v);
64             addedge(v,u);
65         }
66         ans=0;
67         clr(some);
68         dfs(1,1);
69         for(int i=1;i<=n;i++)
70         {
71             diff=n;
72             while(!sta[i].empty())
73             {
74                 p=sta[i].top();
75                 diff-=some[p];
76                 sta[i].pop();
77             }
78             ans+=(LL)diff*(LL)(diff-1)/2;
79         }
80         ans=(LL)n*n*(n-1)/2-ans;
81         printf("%lld\n",ans);
82     }
83     return 0;
84 }
View Code

 

KazaQ‘s Socks

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2375    Accepted Submission(s): 1074


Problem Description
KazaQ wears socks everyday.

At the beginning, he has n技术分享 pairs of socks numbered from 1技术分享 to n技术分享 in his closets.

Every morning, he puts on a pair of socks which has the smallest number in the closets.

Every evening, he puts this pair of socks in the basket. If there are n?1技术分享 pairs of socks in the basket now, lazy KazaQ has to wash them. These socks will be put in the closets again in tomorrow evening.

KazaQ would like to know which pair of socks he should wear on the k技术分享 -th day.
 
 
Input
The input consists of multiple test cases. (about 2000技术分享 )

For each case, there is a line contains two numbers n,k技术分享 (2n10技术分享9技术分享,1k10技术分享18技术分享)技术分享 .
 
 
Output
For each test case, output "Case #x技术分享 : y技术分享 " in one line (without quotes), where x技术分享 indicates the case number starting from 1技术分享 and y技术分享 denotes the answer of corresponding case.
 
 
Sample Input
3 7 3 6 4 9
 
 
Sample Output
Case #1: 3 Case #2: 1 Case #3: 2
 
找找规律嘛,对于每个n 先是第1-n天每天对应1~n,之后按照每天按照(1~n-1),(1~n-2,n)这样的规律不断循环重复,几个if判断下O(1)就可得。
技术分享
 1 #include<bits/stdc++.h>
 2 #define clr(x) memset(x,0,sizeof(x))
 3 #define LL long long
 4 using namespace std;
 5 int main()
 6 {
 7     LL n,k,kase=0,t,l,ans;
 8     while(scanf("%lld%lld",&n,&k)!=EOF)
 9     {
10         printf("Case #%lld: ",++kase);
11         if(k<=n)
12             printf("%lld\n",k);
13         else
14         {
15             k-=n;
16             t=k/(n-1);
17             l=k%(n-1);
18             if(l!=0)
19                 printf("%lld\n",l);
20             else if(t&1)
21                 printf("%lld\n",n-1);
22             else
23                 printf("%lld\n",n);
24         }
25     }
26     return 0;
27 }
View Code

 

2017 Multi-University Training 1 解题报告

标签:this   row   several   long   所有路径   view   选择   计算   preview   

原文地址:http://www.cnblogs.com/wujiechao/p/7240164.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!