[多校补题]2017 Multi-University Training Contest 1 solutions BY 北京航空航天大学

来源:互联网 发布:8097端口 编辑:程序博客网 时间:2024/06/04 18:03

1001. Add More Zero

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 (2m1) (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 from1 to 10k (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 1m105.
 

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

Sample Input
164
 

Sample Output
Case #1: 0Case #2: 19


题意就是10的m次方能转换成2的多少次方,直接求下对数变形一下,得k=m*lg2。
每次O(1)输出即可。

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<cstdlib>using namespace std;const double lg=0.30103;int main(){int tt=1;int m;cout<<log(3)<<endl;while(~scanf("%d",&m)){//cout<<m*lg<<endl;//int res = m*lg;//printf("Case #%d: %d\n",tt++,res);}return 0;}


1002. Balala Power!

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 froma 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 109+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 si consisting of only lower case letters. (1|si|100000,|si|106)
 

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

Sample Input
1a2aabb3abaabc
 

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

每个字符对答案的贡献都可以看作一个 26 进制的数字,问题相当于要给这些贡献加一个 0 到 25 的权重使得答案最大。最大的数匹配 25,次大的数匹配 24,依次类推。排序后这样依次贪心即可,唯一注意的是不能出现前导 0。
因为题目里的数字很大,但是转化成26进制也就100000位,所以考虑用数组的方法储存这些书。先统计每个字母在各个位置上的贡献值,因为你每个位置上的贡献值可能是大于26的,所以要模拟进位。然后按照这个贡献值进行排序,因为题目保证有一个字母是没有出现过的,所以把这个未出现过的字母调到数组首,其余的元素按照贡献值递增排序,之后就按照数组顺序从0到25对他们赋值。这就完成了确定。然后接下来只需要按照每个字母的权值*这个字母在26^j位上的贡献*j位的权重累加即可。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#define ll long longusing namespace std;const  ll mod=1e9+7;char s[120000];int a[27][120000+5];//第i个字母在第j个位置(26^j)的贡献 int b[27];//排序数组 对字母的贡献进行排序 int c[27];//权重数组 记录每个字母最终的贡献权重 ll d[120000];//每个位的数值的大小 26^d[i] int e[27];//记录字母在字符串首是否出现 若未出现过则将其设为0 若都出现则找贡献值最小的那个作为0 void init(){memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(c,0,sizeof(c)); memset(e,0,sizeof(e)); memset(s,0,sizeof(s)); }bool cmp(int x,int y){for(int i=110000;i>=0;i--){if(a[x][i]!=a[y][i])return a[x][i]<a[y][i];}return 0;}int main(){d[1]=1;for(int i=2;i<110000;i++)d[i]=(d[i-1]*26)%mod;int cnn=1;int n;while(~scanf("%d",&n)){init();for(int i=0;i<n;i++){scanf("%s",s);int len = strlen(s);for(int j=len-1;j>=0;j--){//统计各个元素在各个位置出现的次数 a[s[j]-'a'][len-j]++;if(j==0)e[s[j]-'a']=1;}}for(int i=0;i<26;i++){for(int j=1;j<=110000;j++){if(a[i][j]>=26){a[i][j+1]+=a[i][j]/26;a[i][j]%=26;}}} for(int i=0;i<26;i++)b[i]=i;sort(b,b+26,cmp);if(e[b[0]]==1){int start =1;while(e[b[start]]==1&&start<26){start++;}int temp = b[start];for(int i=start-1;i>=0;i--){b[i+1]=b[i];}b[0]=temp;}for(int i=0;i<26;i++)c[b[i]]=i;long long ans=0;for(int i=0;i<=26;i++){for(int j=1;j<=110000;j++){ans=(ans+c[i]*a[i][j]*d[j])%mod;}} printf("Case #%d: %lld\n",cnn++,ans);}return 0;}


1006. Function(待补)

Function

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


Problem Description
You are given a permutation a from 0 to n1 and a permutation b from 0 to m1.

Define that the domain of function f is the set of integers from 0 to n1, and the range of it is the set of integers from 0 to m1.

Please calculate the quantity of different functions f satisfying that f(i)=bf(ai) for each i from 0 to n1.

Two functions are different if and only if there exists at least one integer from 0 to n1 mapped into different integers in these two functions.

The answer may be too large, so please output it in modulo 109+7.
 

Input
The input contains multiple test cases.

For each case:

The first line contains two numbers n, m(1n100000,1m100000)

The second line contains n numbers, ranged from 0 to n1, the i-th number of which represents ai1.

The third line contains m numbers, ranged from 0 to m1, the i-th number of which represents bi1.

It is guaranteed that n106, m106.
 

Output
For each test case, output "Case #xy" 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 21 0 20 13 42 0 10 2 3 1
 

Sample Output
Case #1: 4Case #2: 4

考虑置换a的一个循环节,长度为l,那么有

f(i)=bf(ai)=bbf(aai)=bbf(i)l times b

那么 f(i) 的值在置换 b 中所在的循环节的长度必须为 l 的因数。

而如果 f(i) 的值确定下来了,这个循环节的另外 l1 个数的函数值也都确定下来了。

答案就是ki=1j|lijcalj,其中 k 是置换 a 中循环节的个数, li 表示置换 a 中第 i 个循环节的长度, calj​​ 表示置换 b 中长度为 j 的循环节的个数。

这道题不会做啊....理解不了题意...
已知f(i)=b[f(a(i)],则
f(0) = b[f(a[0])] = b[f(2)]
f[1] = b[f(a[1])] = b[f(0)]
f[2] = b[f(a[2])] = b[f(1)]
其实这道题可以转化为求环的问题,有多少种方式可以构成题目要求的环,即b的环可以有多少种方式画成a的环。



1011. KazaQ's Socks

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 n1 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 (2n109,1k1018).
 

Output
For each test case, output "Case #xy" 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 73 64 9
 

Sample Output
Case #1: 3Case #2: 1Case #3: 2


找规律 若是前n天就直接1-n的穿 从第n+1天开始 以一个周期进行循环 比如n=4 就是1 2 3 4 | 1 2 3 | 1 2 4 | 1 2 3 | 1 2 4 .....
所以有很明显的周期性,每个周期只会改变最后一个数字,在最大的两个数字中周期循环。

#include<iostream>#include<cstdio>using namespace std;int main(){    long long n,k;    int t = 1;    while(scanf("%lld %lld",&n,&k)!=EOF)    {            if(k <= n)        {            printf("Case #%d: %lld\n",t,k);            t++;        }            else        {            long long temp = (k-n)% (n-1);            long long shang = (k-n) / (n-1);                        if(temp == 0)            {                if(shang % 2 == 0)                        printf("Case #%d: %lld\n",t,n);                else                     printf("Case #%d: %lld\n",t,n-1);                t++;            }                        else             {                printf("Case #%d: %lld\n",t,temp);                t++;            }        }                }         return 0;}



第一场官方题解:  BestCoder官方博客


阅读全文
0 0
原创粉丝点击