XJTU Contest 1

来源:互联网 发布:软件维护费用 编辑:程序博客网 时间:2024/06/04 19:39

1000 郭铮鹏与大学计算机基础 (模拟)

Time Limit: 2000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld      Java class name: Main
Submit Status Statistics Discuss
 Next
郭铮鹏经过高中三年的装死生涯之后,顺利地考入了沙坡村男子职业技术学院下水道工程专业。
在大一的大学计算机基础上他第一次接触到了模这个运算,他表示这个运算真是太难啦。
于是他向你求助,由于他知道你不知道比他高到哪里去了,所以他把问题变为求 ABmodC这个表达式的值。希望你能够帮到他。

Input

只有三个整数,A,B,C。满足 0a100,0b10,0<c<100

Output

一个整数,即ABmodC

Sample Input

2 10 7

Sample Output

2

水题,注意b可以等于0,所以最后还需要对c取模(没看数据范围,WA了)

#include <cstdio>using namespace std;int main() {    int a,b,c,ans;    while(3==scanf("%d%d%d",&a,&b,&c)) {        ans=1;        while(b-->0) {            ans=(ans*a)%c;        }        printf("%d\n",ans%c);    }    return 0;}


1001 郭铮鹏与约会 (模拟)

Time Limit: 2000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld      Java class name: Main
Prev 
Submit Status Statistics Discuss
 Next

有一天,郭铮鹏想去见一见他远在他乡的基友J,并且玩一玩他的Xbox。郭铮鹏和J都生活在笛卡尔坐标下。郭铮鹏的家在点(0,0)而J的家在点(a,b)。郭铮鹏每一次可以横向或者纵向移动一步。也就是说,他能从(x,y)移动到(x+1,y),(x-1,y),(x,y+1)或(x,y-1). 不幸的是,郭铮鹏这个人没有方向感。所以他每一步都随机选择一个方向来行走。郭铮鹏可能凑巧的走着走着又走回了他家。郭铮鹏甚至会到达基友家门口但意识不到,然后继续行走。 幸运的是,郭铮鹏成功地到达了(a,b)。到了之后他和J吹嘘:"我走了s步才走到你家呢"。但J不是很相信郭铮鹏的这句话,他不确定从(0,0)走到(a,b)走s步是否是可能的。你能帮J确定这是否可能吗?

Input

输入由多组数据组成,每组数据一行,为三个整数a,b,s(109a,b109,1s2×109)。处理到文件结束。
 

Output

对于每组数据,输出一行,如果无法走到,输出"No",否则输出"Yes"。

Sample Input

5 5 1110 15 250 5 10 0 2

Sample Output

NoYesNoYes

水题,(0,0)到(a,b)最少要走a+b步,如果s<abs(a)+abs(b),则必定不能到达,若s>=abs(a)+abs(b),则s与a+b奇偶性相同时(即 s-abs(a)-abs(b) 为偶数),可达,否则不可达。(没看数据范围,又WA了...)

#include <cstdio>#include <algorithm>using namespace std;int main() {    int a,b,s;    while(3==scanf("%d%d%d",&a,&b,&s)) {        if(s<abs(a)+abs(b)) {            printf("No\n");        }        else {            printf("%s\n",((s-abs(a)-abs(b))&1)==0?"Yes":"No");        }    }    return 0;}

1002 郭铮鹏与杯垫 (模拟)

Time Limit: 2000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld      Java class name: Main
Prev 
Submit Status Statistics Discuss
 Next
郭铮鹏想在商店中买w个西安交大校庆纪念杯垫,但这个商店非常坑,郭铮鹏需要付k元买第一个杯垫,2k元买第二个杯垫,以此泪推(也就是说,他需要付i*k元买第i个杯垫)。
郭铮鹏现在有n元,他不一定买得起所有杯垫,但好在他有一个土豪朋友。他需要从这位朋友那里借多少钱才能从这个黑心店里买到w个杯垫呢?

Input

输入由多组数据组成,每组数据一行,为三个整数k,n,w(1k,w1000,0n109),分别表示第一个杯垫的售价、郭铮鹏一开始手上的钱数和他想要的杯垫数量(单位:元)。

Output

对于每组数据,输出一个整数,表示郭铮鹏至少需要借的钱,如果他不需要借钱,输出0。

Sample Input

3 17 4

Sample Output

13

这题是某次CF的A题

依旧水题,统计总共需要的钱,然后判断即可

#include <cstdio>#include <algorithm>using namespace std;int main() {    int k,n,w,ans;    while(3==scanf("%d%d%d",&k,&n,&w)) {        ans=(k+w*k)*w/2-n;        printf("%d\n",ans<=0?0:ans);    }    return 0;}

1003 郭铮鹏与比赛 (排序)

Time Limit: 2000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld      Java class name: Main
Prev 
Submit Status Statistics Discuss
 Next
郭铮鹏很喜欢编程比赛。他正在准备一场新的比赛。
这次比赛一共有n个学生参加,在比赛开始之前,每一个学生有一个正整数的得分。学生编号从1到n。第i个学生的得分为ai。比赛结束之后,每个学生都会有一个排名,郭铮鹏希望学生的排名根据他们的得分来定。
他认为每一个学生的排名应该等于"1+得分比该学生高的学生数量".如果学生A的得分比B低,那么A的排名就会比B低,而如果两位学生有相同的得分,他们的排名就是相同的。
郭铮鹏希望你按照他的要求得出比赛结果,也就是每个同学在他的排名规则下的排名。

Input

输入由多组数据组成。
每组数据第1行为一个正整数n(1n2000),表示参加比赛的学生数量。
第二行为n个整数a1,a2,,an(1ai2000),ai表示第i个学生的得分。

Output

对于每组数据输出一行,按照输入的顺序输出每个学生的排名。每两个整数用一个空格隔开。

Sample Input

31 3 31153 5 3 4 5

Sample Output

3 1 114 1 4 3 1

排序,然互赋予每个成绩排名即可

数据小,所以每次找最小的标记排名也可

#include <cstdio>#include <algorithm>using namespace std;struct Node {    int i,a;    bool operator < (const Node& b) const {        return a>b.a;    }}s[2005];int n,rnk[2005];int main() {    int cur,cnt;    while(1==scanf("%d",&n)) {        for(int i=0;i<n;++i) {            s[i].i=i;            scanf("%d",&s[i].a);        }        sort(s,s+n);        cur=1;        cnt=1;        rnk[s[0].i]=1;        for(int i=1;i<n;++i) {            if(s[i].a!=s[i-1].a) {                cur+=cnt;                cnt=0;            }            ++cnt;            rnk[s[i].i]=cur;        }        printf("%d",rnk[0]);        for(int i=1;i<n;++i) {            printf(" %d",rnk[i]);        }        printf("\n");    }    return 0;}

1004 郭铮鹏与书 (模拟)

Case Time Limit: 2000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld      Java class name: Main
Prev 
Submit Status Statistics Discuss
 Next
郭铮鹏有一个重要的任务--他需要把图书馆里的书都拿出来然后给每一本书贴一个标签,标签上面是这本书的编号。n本书会被编号为1到n。不同的书编号不能相同。
郭铮鹏想要知道他写下这些数的编号一共需要写多少个数字。

Input

输入由多组数据组成。每组数据一行,包含一个整数n(1n109 ),表示图书馆里书的总数。

Output

对于每组数据,输出一个整数,表示给这些书编号需要写的数字位数之和。

Sample Input

134

Sample Output

174
按位数统计数字即可,得用long long,没用debug半天...

int n;long long lim[11]={0,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,1000000001};long long ans;int main() {    while(1==scanf("%d",&n)) {        ans=0;        for(long long i=1;i<=10&&lim[i-1]<=n;++i) {            if(n>=lim[i]) {                ans+=i*(lim[i]-lim[i-1]);            }            else {                ans+=i*(n-lim[i-1]+1);            }        }        printf("%lld\n",ans-1LL);    }    return 0;}

1005 GZP and Poker (数学)

Case Time Limit: 2000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld      Java class name: Main
Prev 
Submit Status Statistics Discuss
 Next
GZP often plays games with his friends.Today they went to a board game.There are n players(including GZP) and all of them have some virtual money on the table. ith of them has ai yuan.
Each player can double his virtual wealth any number of times and triple his virtual wealth any number of times.The game has a big prize for making wealth of all players equal.Is it possible for GZP and his friends to win the big prize?

Input

The input consists of several test cases.
First line of input contains an integer n(2n105),the number of players.
The second line contains n integer numbers a1,a2,,an(1ai109)-the virtual money of players.

Output

For each test case, print a line.
"Yes"(without the quotes)if players can make their wealth equal, or "No" otherwise.

Sample Input

475 150 75 503100 150 250

Sample Output

YesNo

题目大意:给定n个数,每个数a[i]可以变成a[i]*(2^p)*(3^q)(p,q>=0,p,q可取任意值),问这n个数经过变换后是否能相同?

第一反应就是:设所有a[i]的最大公约数为gcd,若要变换后能相同,则a[i]/gcd的质因子只有2和3


若a[i]/gcd还存在其他质因子z,则z无法通过(2^m)*(3^n)获得,则其他数经过变换后必定不能形成与a[i]变换后想等的数

#include <cstdio>#include <algorithm>using namespace std;int n,gcd,a[100005];bool flag;int main() {    while(1==scanf("%d",&n)) {        flag=true;        scanf("%d",a);        gcd=a[0];        for(int i=1;i<n;++i) {            scanf("%d",a+i);            gcd=__gcd(gcd,a[i]);        }        for(int i=0;i<n;++i) {            a[i]/=gcd;            while(a[i]%3==0) {                a[i]/=3;            }            while(a[i]%2==0) {                a[i]/=2;            }            if(a[i]!=1) {                flag=false;                break;            }        }        printf("%s\n",flag?"Yes":"No");    }    return 0;}


——————————————————6题的旅游分割线———————————————————

本来不想写的,但是限于环境问题,3h就写了一道最大流,绝得效率太低,就在最后1h写了一下,发现前6题还挺简单...

估计英文第一题,才是真正的A题

1006 GZP and Counting (模拟)

Case Time Limit: 2000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld      Java class name: Main
Prev 
Submit Status Statistics Discuss
 Next
GZP loves counting. One day a friend of GZP gave him a complicated counting problem. 
GZP was given a string S consisting of lowercase letters, and his task was counting the number of substrings that for each lowercase letter it appears no more than K times in the substring.
It seems too difficult for GZP to count them. So he finds you. As a good programmer, can you solve this problem for him?

Input

The input consists of several test cases.In the first line there is an integer T(1T100), indicates the number of test cases.
For each case, the first line contains a string S, which only consist of lowercase letters(1 the length of S  100000). The second line contains an integer K(1K100000).

Output

For each case, output a line contains the answer.

Sample Input

3abc1abcabc1abcabc2

Sample Output

61521
题目大意:给定一个只含小写字母的字符串,统计满足限制的子串数目,子串中出现次数最多的字符出现次数不超过k。

正难则反,首先所有子串的数目很容易求出,所以只要求出不符合题意的子串就行

将每个字符每次出现的下标存入队列,当有字符出现次数超过k时,就开始减去不符合的子串,每次只计算以当前字符为结尾的不符合的子串即可,为了不漏掉不符合的,用last表示到当前字符时,存在不符合子串的起始的最靠后的下标,然后不符合的子串数就是last+1

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int k,len,cur,last;int tail[26];int q[26][100005];char s[100005];long long ans;int main() {    int T;    scanf("%d",&T);    while(T-->0) {        scanf("%s%d",s,&k);        memset(tail,0,sizeof(tail));        ans=0;        last=-1;//last表示存在重复不符合题意的子串的最靠后的起始下标        for(len=0;s[len]!='\0';++len) {            cur=s[len]-'a';            q[cur][tail[cur]++]=len;            if(tail[cur]>k) {                last=max(last,q[cur][tail[cur]-k-1]);//更新最靠后的起始下标            }            ans-=last+1;//减去以当前字符为结尾的不符合题意的子串数        }        ans+=(1LL+len)*len/2;//最后再加上总的子串数        printf("%lld\n",ans);    }    return 0;}



1007 GZP and world of single-dogs (计算几何)

Case Time Limit: 2000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld      Java class name: Main
Prev 
Submit Status Statistics Discuss
 Next
By research conducted by GZP, we will soon have a breakthrough to understand time, universe and love. According to that, the universe in common sense is not the only one. Multi World Line is running at the same time. Simply, let us use a straight line in 3-D space to indicate a single World Line.
 
And simply, there are two World Lines. In World Line Alpha, where we are living in, there are some people and phenomena keeping hurting single dogs like GZP. And, in World Line Beta, which everybody can also be single but happy. So GZP want to get to World Line Beta deadly, he want to find the shortest path between World Line Alpha and World Line Beta.
 

Input

The first line contains an integer T, indicating the number of test cases. 
Each case contains only one line with 12 float numbers (x1, y1, z1), (x2, y2, z2), (x3, y3, z3), (x4, y4, z4), correspondingly indicating two points in World Line Alpha and World Line Beta. Note that a World Line is a 3-D line with infinite length. 
Data satisfy T <= 10000, |x, y, z| <= 10,000.

Output

For each test case, please print two lines.
The first line contains one float number, indicating the length of shortest path. 
The second line contains 6 float numbers (xa, ya, za), (xb, yb, zb), seperated by blank, correspondingly indicating the endpoints of the shortest path between World Line Alpha and World Line Beta. 
All the output float number should be round to 4 digits after decimal point. Data guarantees the uniqueness of the shortest path.

 

Sample Input

11 0 1 0 1 1 0 0 0 1 1 1

Sample Output

0.40820.5000 0.5000 1.0000 0.6667 0.6667 0.6667
一眼就看出来是高中数学解析几何,可以已经忘了...真是悲伤

找了个模版AC掉...

完整三维计算几何模版

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const double EPS=0.000001;typedef struct Point_3D {    double x, y, z;    Point_3D(double xx = 0, double yy = 0, double zz = 0): x(xx), y(yy), z(zz) {}    bool operator == (const Point_3D& A) const {        return x==A.x && y==A.y && z==A.z;    }}Vector_3D;Point_3D read_Point_3D() {    double x,y,z;    scanf("%lf%lf%lf",&x,&y,&z);    return Point_3D(x,y,z);}Vector_3D operator + (const Vector_3D & A, const Vector_3D & B) {    return Vector_3D(A.x + B.x, A.y + B.y, A.z + B.z);}Vector_3D operator - (const Point_3D & A, const Point_3D & B) {    return Vector_3D(A.x - B.x, A.y - B.y, A.z - B.z);}Vector_3D operator * (const Vector_3D & A, double p) {    return Vector_3D(A.x * p, A.y * p, A.z * p);}Vector_3D operator / (const Vector_3D & A, double p) {    return Vector_3D(A.x / p, A.y / p, A.z / p);}double Dot(const Vector_3D & A, const Vector_3D & B) {    return A.x * B.x + A.y * B.y + A.z * B.z;}double Length(const Vector_3D & A) {    return sqrt(Dot(A, A));}double Angle(const Vector_3D & A, const Vector_3D & B) {    return acos(Dot(A, B) / Length(A) / Length(B));}Vector_3D Cross(const Vector_3D & A, const Vector_3D & B) {    return Vector_3D(A.y * B.z - A.z * B.y, A.z * B.x - A.x * B.z, A.x * B.y - A.y * B.x);}//空间两直线上最近点对 返回最近距离 点对保存在ans1 ans2中double SegSegDistance(Point_3D a1, Point_3D b1, Point_3D a2, Point_3D b2, Point_3D& ans1, Point_3D& ans2){    Vector_3D v1 = (a1 - b1), v2 = (a2 - b2);    Vector_3D N = Cross(v1, v2);    Vector_3D ab = (a1 - a2);    double ans = Dot(N, ab) / Length(N);    Point_3D p1 = a1, p2 = a2;    Vector_3D d1 = b1 - a1, d2 = b2 - a2;    double t1, t2;    t1 = Dot((Cross(p2 - p1, d2)), Cross(d1, d2));    t2 = Dot((Cross(p2 - p1, d1)), Cross(d1, d2));    double dd = Length((Cross(d1, d2)));    t1 /= dd * dd;    t2 /= dd * dd;    ans1 = (a1 + (b1 - a1) * t1);    ans2 = (a2 + (b2 - a2) * t2);    return fabs(ans);}int main() {    int T;    Point_3D a1,a2,b1,b2,ans1,ans2;    double dis;    scanf("%d",&T);    while(T-->0) {        a1=read_Point_3D();        a2=read_Point_3D();        b1=read_Point_3D();        b2=read_Point_3D();        dis=SegSegDistance(a1,a2,b1,b2,ans1,ans2);        printf("%.4lf\n",dis);        printf("%.4lf %.4lf %.4lf %.4lf %.4lf %.4lf\n",ans1.x,ans1.y,ans1.z,ans2.x,ans2.y,ans2.z);    }    return 0;}



1008 GZP and CS (数位DP)

Case Time Limit: 2000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld      Java class name: Main
Prev 
Submit Status Statistics Discuss
 Next
GZP love to play Counter-Strike(CS).
One day GZP was playing a mod of CS.
The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "96", the power of the blast would add one point.
Now GZP knows the number N. Only when the computing result of the final points of the power by GZP is correct can he attain success.Can you help him?

Input

The first line of input consists of an integer T (1 <= T <= 100), indicating the number of test cases. For each test case, there will be an integer N (1 <= N <= 2^63-1) as the description.

Output

For each test case, output an integer indicating the final points of the power.

Sample Input

31100500

Sample Output

015

Hint

From 1 to 500, the numbers that include the sub-sequence "96" are "96","196","296","396","496",so the answer is 5.

题目大意:统计1~n中数字中含有连续96的数字个数?


一道裸的数位DP

官方标程错了,我写的一直WA,看了一个AC的代码,很明显发现有错...

#include <cstdio>using namespace std;int num[25],len;long long n,ans;long long dp[25][3];//dp[i][0]表示长度为i,且不含96的数字个数;dp[i][1]表示长度为i,不含96且最高位为6的数字个数;dp[i][2]表示长度为i,且含有96的数字个数void Init() {    dp[0][0]=1;    dp[0][1]=dp[0][2]=0;    for(int i=1;i<=20;++i) {        dp[i][0]=dp[i-1][0]*10-dp[i-1][1];//长度为i-1且不含96的数字,最高位可加上0~9;但若最高位加上9,而次高位为6则不满足,所以要减去        dp[i][1]=dp[i-1][0];//长度为i-1,不含96的数字,最高位可加上9        dp[i][2]=dp[i-1][2]*10+dp[i-1][1];//长度为i-1且含96的数字,最高位可加上0~9;长度为i-1,不含96且最高位为6,则目前最高位可加上9    }}long long getCnt(long long x) {//返回[1,x]中含有49的数字个数    ++x;    ans=len=0;    while(x>0) {        num[++len]=x%10;        x/=10;    }    num[len+1]=-1;    bool flag=false;//表示高位是否出现过96,true表示出现过    for(int i=len;i>=1;--i) {//从最高位开始枚举        ans+=dp[i-1][2]*num[i];//低i-1位中出现96的数字,当前位可取0~(num[i]-1)        if(flag) {//如果高位出现过96            ans+=dp[i-1][0]*num[i];//高位出现过96,低i-1位没有出现过96,当前位可取0~(num[i]-1)        }        if(!flag&&num[i+1]==9&&num[i]>6) {            ans+=dp[i-1][0];//高位未出现过96,且上一位为9,当前位大于6,则当前位可以取6,则低i-1为可任取不含96的数字        }        if(num[i+1]==9&&num[i]==6) {//若该位与上一位能组成96            flag=true;        }    }    return ans;}int main() {    Init();    int T;    scanf("%d",&T);    while(T-->0) {        scanf("%lld",&n);        printf("%lld\n",getCnt(n));    }    return 0;}


1009 GZP and Date II (贪心&&Lucas定理)

Case Time Limit: 2000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld      Java class name: Main
Prev 
Submit Status Statistics Discuss
 Next
Someday, GZP wants to go on date with H.GZP and H live on Cartesian plane. GZP's home is located in point(0,0) and H's home is located in point(N,M). In each step, he can move in a unit distance in horizonal or vertical direction. In other words, from position(x,y) he can go to positions (x+1,y), (x-1,y), (x,y+1) or (x,y-1).
Every time GZP arrives to a position, he needs to spend some energy. Let C(x,y) be the amount of energy GZP should spend when he arrives to point (x,y).
C(x,y) can be calculated like this:
1. if x = 0 or y = 0, C(x,y) = 1
2. if x > 0 and y > 0, C(x,y) = C(x,y-1) + C(x-1,y)
3. if x < 0 or y < 0 C(x,y) = infinite.
Now GZP wants to know the least total amount of energy he should spend to get from(0,0) to (N,M)(Note that the amount of arriving to (0,0) should also be calculated).

Input

The first line contains an integer T, indicating the number of test cases.
Each test case consists of 2 numbers N, M(0<=N, M<=10^12,N*M<=10^12).

Output

For each case, output the answer mod (1e9+7) in a line.

Sample Input

21 22 3

Sample Output

618
题目大意:定义在到达(x,y)的花费为c(x,y)

1. if x = 0 or y = 0, c(x,y) = 1
2. if x > 0 and y > 0, c(x,y) = c(x,y-1) + c(x-1,y)
3. if x < 0 or y < 0 c(x,y) = infinite.

每次只能向相邻的一个格子走,求从(0,0)走到(n,m)的最小花费?


大致思路:先手动写上小数据的各个格子的花费,可以看出做左上角开始的副对角线是二项式系数(杨辉三角)

又可以发现,要想花费最少,则必定只走n+m步,可以先贪心地走到(0,m)【n<=m时】 或 (n,0)【n>m时】

则转换为计算组合数了

不妨设n<=m

则答案为:m+1+C(m,1)+C(m+1,2)+…+C(m+n+1,n)=m+C(m,0)+C(m,1)+C(m+1,2)+…+C(m+n,n-1)

利用组合数性质: C(n,m)= C(n,n-m)= C(n-1,m-1)+C(n-1,m)

可得:m+C(m+n+1,n)

随便找了个模版,效率好低,跑了450ms,别人都是50ms...

换了这个模版后,瞬间变成16ms,看来模版的效率不容忽视

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const LL MOD=1e9+7;LL n,m;LL quick_pow(LL a, LL b) {    LL ans = 1;    a %= MOD;//防止指数为0时,返回未取模的结果    while(b!=0) {        if((b & 1)==1) {            ans = ans * a % MOD;        }        b >>= 1;        a = a * a % MOD;    }    return ans;}LL C(LL n, LL m) {    if(n < m) {        return 0;    }    if(n == m) {        return 1;    }    if(m > n - m) {//利用组合数性质,减少运算次数        m=n - m;    }    LL ans, a = 1, b = 1;    for(int i=0; i<m; ++i) {        a = (a * (n - i)) % MOD;        b = (b * (m - i)) % MOD;    }    ans = (a * quick_pow(b, MOD-2)) % MOD;    return ans;}LL Lucas(LL n, LL m) {    LL ans=1;    while(m>0) {        ans=(ans*C(n % MOD, m % MOD)) % MOD;        n/=MOD;        m/=MOD;    }    return ans;}int main() {    int T;    scanf("%d",&T);    while(T-->0) {        scanf("%lld%lld",&n,&m);        if(n>m) {            swap(n,m);        }        printf("%lld\n",(Lucas(m+n+1,n)+m)%MOD);    }    return 0;}



0 0