FJNU 第二十二届低年级程序设计竞赛部分题解

http://47.106.223.193/contest.php?cid=1001

B:题意:给出 a 的出发时间范围x1~x2,a 的行程时间,b 的出发时刻,b 的行程时间,问 a 能抓到 b 的概率

题解:很容易想到当 a 的最晚到达时间比 b 的到达时间早,那么a 100%能抓到 b,如果 b 在 a的最早到达时间前到达目的地,那么

a 肯定抓不到 b ,剩下的所有情况只要用 b 的到达时间减去 a 的最早到达时间再除以 a 的时间跨度就是答案

/***                                                                    
 *            .,,       .,:;;iiiiiiiii;;:,,.     .,,                   
 *          rGB##HS,.;iirrrrriiiiiiiiiirrrrri;,s&##MAS,                
 *         r5s;:r3AH5iiiii;;;;;;;;;;;;;;;;iiirXHGSsiih1,               
 *            .;i;;s91;;;;;;::::::::::::;;;;iS5;;;ii:                  
 *          :rsriii;;r::::::::::::::::::::::;;,;;iiirsi,               
 *       .,iri;;::::;;;;;;::,,,,,,,,,,,,,..,,;;;;;;;;iiri,,.           
 *    ,9BM&,WA了活该       .,:;;:,,,,,,,,,,,hXA8:   T了天命..,,,.       
 *   ,;&@@#r:;;;;;::::,,.   ,r,,,,,,,,,,iA@@@s,,:::;;;::,,.   .;.      
 *    :ih1iii;;;;;::::;;;;;;;:,,,,,,,,,,;i55r;;;;;;;;;iiirrrr,..       
 *   .ir;;iiiiiiiiii;;;;::::::,,,,,,,:::::,,:;;;iiiiiiiiiiiiri         
 *   iriiiiiiiiiiiiiiii;;;::::::::::::::::;;;iiiiiiiiiiiiiiiir;        
 *  ,riii;;;;;;;;;;;;;:::::::::::::::::::::::;;;;;;;;;;;;;;iiir.       
 *  iri;;;::::,,,,,,,,,,:::::::::::::::::::::::::,::,,::::;;iir:       
 * .rii;;::::,,,,,,,,,,,,:::::::::::::::::,,,,,,,,,,,,,::::;;iri       
 * ,rii;;;::,,,,,,,,,,,,,:::::::::::,:::::,,,,,,,,,,,,,:::;;;iir.      
 * ,rii;;i::,,,,,,,,,,,,,:::::::::::::::::,,,,,,,,,,,,,,::i;;iir.      
 * ,rii;;r::,,,,,,,,,,,,,:,:::::,:,:::::::,,,,,,,,,,,,,::;r;;iir.      
 * .rii;;rr,:,,,,,,,,,,,,,,:::::::::::::::,,,,,,,,,,,,,:,si;;iri       
 *  ;rii;:1i,,,,,,,,,,,,,,,,,,:::::::::,,,,,,,,,,,,,,,:,ss:;iir:       
 *  .rii;;;5r,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,sh:;;iri        
 *   ;rii;:;51,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.:hh:;;iir,        
 *    irii;::hSr,.,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.,sSs:;;iir:         
 *     irii;;:iSSs:.,,,,,,,,,,,,,,,,,,,,,,,,,,,..:135;:;;iir:          
 *      ;rii;;:,r535r:...,,,,,,,,,,,,,,,,,,..,;sS35i,;;iirr:           
 *       :rrii;;:,;1S3Shs;:,............,:is533Ss:,;;;iiri,            
 *        .;rrii;;;:,;rhS393S55hh11hh5S3393Shr:,:;;;iirr:              
 *          .;rriii;;;::,:;is1h555555h1si;:,::;;;iirri:.               
 *            .:irrrii;;;;;:::,,,,,,,,:::;;;;iiirrr;,                  
 *               .:irrrriiiiii;;;;;;;;iiiiiirrrr;,.                    
 *                  .,:;iirrrrrrrrrrrrrrrrri;:.                        
 *                        ..,:::;;;;:::,,.                             
 */ 
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<vector> 
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem(a,b) memset(a,b,sizeof(a));
#define lowbit(x)  x&-x;  
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int maxn = 1e5+5;
const int mod = 1e9+7;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int Time(int x1,int x2,int x3){
    return x1*3600+x2*60+x3;
}
 
int a[3][6];
 
int main() {
    int t;
    cin>>t;
    while(t--){
        scanf("%d:%d:%d",&a[0][1],&a[1][1],&a[2][1]);
        scanf("%d:%d:%d",&a[0][2],&a[1][2],&a[2][2]);
        scanf("%d:%d:%d",&a[0][3],&a[1][3],&a[2][3]);
        scanf("%d:%d:%d",&a[0][4],&a[1][4],&a[2][4]);
        scanf("%d:%d:%d",&a[0][5],&a[1][5],&a[2][5]);
        int x1,x2,x3,x4;
        int t1 = Time(a[0][1],a[1][1],a[2][1]);
        int t2 = Time(a[0][2],a[1][2],a[2][2]);
        int y1 = Time(a[0][3],a[1][3],a[2][3]);
        int y2 = Time(a[0][5],a[1][5],a[2][5]);
        int jia = Time(a[0][4],a[1][4],a[2][4]);
        x1 = t1+y1;
        x2 = t2+y1;
        x3 = jia;
        x4 = x3+y2;
        if(x2 <= x4) cout<<"1.00"<<endl;
        else if(x4 < x1) cout<<"0.00"<<endl;
        else{
            printf("%.2f\n",1.0*(x4-x1+1)/(x2-x1+1));
        }
    }
}

D:题意:(不想说了。。。。看题目挺好理解的)

jq定义一个数的表示方法为x(n) = (a1,a2,a3,a4.,..an),ai(1<=i<=n)是一个三位数(可能包含前导0,比如001) 
x(n)是一个3*n位的数,x = a1a2a3..an,例如123456(2) = (123,456)。
 jq自定义一个位数相同的两个数的乘法运算为: 
                                                    x(n)*y(n) = (a1*b1%1000,a2*b2%1000,a3*b3%1000,....,an*bn%1000) = z(n) 
例如123456(2)*456123(2) = (123*456%1000,456*123%1000) = (088,088) = 088088; 
现在jq想用这个规则考一考fuls,jq给了fuls一个3*n位数的数z,要求fuls求出两个3*n位数的数x,y使得它们用上面定义的乘法乘积等于z。 
聪明的fuls一下子就解出了x和y,于是他在当晚就把答案写在了纸上,等他醒来时发现x和y的某些ai,bj(1<=i,j<=n)的数已模糊不清(估计是jq干的)(如果某个ai或者bj模糊不清,那么代表其三位数都模糊不清)。 

然后求出这个最小的x和y,优先x最小,然后y最小

题解:因为答案最多000~999,所以用一个vector记录对于每一个三位数字,它的所有组合情况,然后再用两个数组分别记录对于每一个数字,他有因子x时,y的最小值,他有因子y时,x的最小值,方便后续查询。然后排序一下,就很容易在后续查询中求出答案。

之后就是进行s2,s3的分类讨论。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<vector> 
using namespace std;
#define inf 0x3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem(a,b) memset(a,b,sizeof(a));
#define lowbit(x)  x&-x;  
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int maxn = 1e6 + 5;
const int mod = 1e9 + 7;
inline int read()
{
    int x = 0, f = 1; char ch = getchar();
    while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x*f;
}
struct node {
    int x, y;
    node(int a,int b):x(a),y(b){}
};
bool cmp(node a, node b) {
    if (a.x == b.x) return a.y < b.y;
    return a.x < b.x;
}
vector<node>v[1005];
int inv1[1005][1005], inv2[1005][1005];
void init() {
    /*for (int i = 0; i < 1000; i++)
        v[i].clear();*/
    mem(inv1, inf);
    mem(inv2, inf);
    for (int i = 0; i < 1000; i++) {
        for (int j = 0; j < 1000; j++) {
            int res = i*j % 1000;
            v[res].push_back(node(i,j));
            inv1[res][i] = min(j, inv1[res][i]);
            inv2[res][j] = min(i, inv2[res][j]);
        }
    }
    for (int i = 0; i < 1000; i++) {
        sort(v[i].begin(), v[i].end(),cmp);
    }
}
char s1[3*maxn], s2[3*maxn], s3[3*maxn];
char ans1[3 * maxn + 5], ans2[3 * maxn + 5];
int getnum(char s[]) {
    if (s[0] == '*') return 0;
    int sum = 0;
    for (int i = 0; i < 3; i++) {
        sum = 10 * sum + s[i] - '0';
    }
    return sum;
}
char str1[4], str2[4], str3[4];
int main() {
    init();
    int t;
    int a1, a2;
    cin>>t;
    while (t--) {
        int n;
        scanf("%d", &n);
        mem(ans1,0);
        mem(ans2,0);
        scanf("%s%s%s", s1, s2, s3);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < 3; j++) {
                str1[j] = s1[3 * i + j];
                str2[j] = s2[3 * i + j];
                str3[j] = s3[3 * i + j];
            }
            int n1 = getnum(str1), n2 = getnum(str2), n3 = getnum(str3);
            if (!n2 && !n3) {
                a1 = v[n1][0].x;
                a2 = v[n1][0].y;
                if (a1 > a2) swap(a1, a2);
                //printf("1.0 %d %d\n",a1,a2);
            }
            else if (!n2 && n3) {
                a1 = inv2[n1][n3];
                a2 = n3;
                //printf("2.0 %d %d\n",a1,a2);
            }
            else if (n2 && !n3) {
                a1 = n2;
                a2 = inv1[n1][n2];
                //printf("3.0 %d %d\n",a1,a2);
            }
            else {
                a1 = n2;
                a2 = n3;
            }
            for (int j = 2; j >= 0; j--) {
                ans1[3 * i + j] = a1 % 10 + '0';
                a1 /= 10;
                ans2[3 * i + j] = a2 % 10 + '0';
                a2 /= 10;
            }
        }
        //ans1[3 * n] = '\0', ans2[3 * n] = '\0';
        printf("%s\n%s\n", ans1, ans2);
    }
}

F:题意:给出字符串长度n,这个字符串只能由A,C组成,要求 满足 “CA” (C,A可以不连续,但是C必须在A前面)对数为m的最大字典序的字符串。

题解:很容易可以证明,当A的个数为x时,这个字符串的CA对数为 x*(n-x),因此先预处理出A的每一种个数能够提供的最大CA对数,查询出第一个大于等于m的最大对数,那么他的下标就是答案字符串中A字符的个数,那么每一个A之前C的个数就可以得到了。

注意并不是每一个A之前C的个数都一样,所以可以我们可以先假装一样,然后将最后一个C往前插入,具体看代码吧。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<vector> 
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem(a,b) memset(a,b,sizeof(a));
#define lowbit(x)  x&-x;  
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int maxn = 1e5+5;
const int mod = 1e9+7;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int sum[105];
char ans[105];
int n,m;
int main() {
	int t;
	cin>>t;
	while(t--){
		scanf("%d%d",&n,&m);
		if(m == 0){
			for(int i = 1; i <= n; i++)
				printf("C");
			puts("");
			continue;
		}
		for(int i = 0; i <= n; i++){
			sum[i] = i*(n-i);
		}
		mem(ans,0);
		int pos = 0;
		int flag = 0;
		for(int i = 0; i <= n; i++){
			//cout<<sum[i]<<endl;
			if(m <= sum[i]){
				pos = i;  //需要的A的个数
				flag = 1;
				break;
			}
		}
		//cout<<pos<<endl;
		if(!flag) puts("jq lost fuls!");
		else{
			int res = m/pos;  //每一个A前C的个数
			int ju = m%pos;  //如果余数为0,每一个A前C的个数为res,否则就说明有些A前面不止res个C,余数一定小于pos,所以我们先按照顺序排列好字符串,然后将最后的C(如果有的话)往前移动ju个
			if(ju){
				int cnt = 0;
				for(int i = 1; i <= res; i++)
					ans[cnt++] = 'C';
				for(int i = 1; i <= pos-ju; i++)
					ans[cnt++] = 'A';
				ans[cnt++] = 'C';
				for(int i = 1; i <= ju; i++)
					ans[cnt++] = 'A';
				int x = n-res-pos;
				for(int i = 1; i <= x-1; i++)
					ans[cnt++] = 'C';
				puts(ans);
				continue;
			}
			int cnt = 0;
			for(int i = 1; i <= res; i++){
				ans[cnt++] = 'C';
			}
			for(int i = 1; i <= pos; i++){
				ans[cnt++] = 'A';
			}
			int x = n-res-pos;
			for(int i = 1; i <= x; i++)
				ans[cnt++] = 'C';
			puts(ans);
		}
	}
}

G:似乎是原题?

题意:半径为R的桌子上摆放半径为 r 的盘子,每个盘子必须靠着桌子边缘,问能否摆 n 张盘子

题解: 画个图就出来了(现场很早就开这题,但是由于图画的丑不拉几的就懒得去做了。。。)

asin()函数求出每张盘子所占弧度,pi / asin()就表示一个圆周可以放几张盘子,最后和n比较下,注意下几个特判就好了

(出题人没卡精度还算良心哈哈哈哈)

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<vector> 
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem(a,b) memset(a,b,sizeof(a));
#define lowbit(x)  x&-x;  
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-8;
const int maxn = 1e5+5;
const int mod = 1e9+7;
const double pi = acos(-1.0);
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,R,r;
int main() {
    while(~scanf("%d%d%d",&n,&R,&r)){
        double an = 0;
        //printf("%f\n",asin(0.5)*180/pi);
        if(n == 1){
            if(R < r) puts("NO");
            else puts("YES");
        }else if(n == 2){
            if(R >= 2*r) puts("YES");
            else puts("NO");
        }else{  
            an = pi/(asin(1.0*r/(R-r)));
            if((int)(an) < n) puts("NO");
            else puts("YES");
        }
    }
}
 

H:题意:数组a累乘除以数组b累乘,问结果是否为质数(这里的除就是广义的除法,不是向下取整)

题解:对a的每一个元素分解质因数,用一个sum数组记录每一个分解出来的质因数的个数,然后对b分解质因数,每分解出一个,就对sum数组中对应元素的个数减减,如果b中存在某一质因数在数组中不存在,那么输出NO。b数组分解完后再寻找一下sum中每种质因数的个数之和,如果大于1,就输出NO,否则输出YES。(原理就是唯一分解定理,每一个数都可以分解成若干个质因数的乘积)

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<vector> 
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem(a,b) memset(a,b,sizeof(a));
#define lowbit(x)  x&-x;  
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int maxn = 1e5+5;
const int mod = 1e9+7;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m;
int a[maxn],b[maxn];
int num[maxn];
int main() {
    while(~scanf("%d%d",&n,&m)){
        mem(num,0);
        for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
        for(int i = 1; i <= m; i++) scanf("%d",&b[i]);
        ll sum = 0;
        for(int i = 1; i <= n; i++){
            for(int j = 2; j*j <= a[i]; j++){
                while(a[i]%j==0){
                    num[j]++;
                    a[i] /= j;
                }
            }
            if(a[i] > 1){
                num[a[i]]++;
            }
        }
        int cnt = 0,flag = 0;
        for(int i = 1; i <= m; i++){
            for(int j = 2; j*j <= b[i]; j++){
                while(b[i]%j==0){
                    if(num[j]){
                        num[j]--;
                    }else{
                        flag = 1;
                        break;
                    }
                    b[i] /= j;
                }
                if(flag) break;
            }
            if(flag) break;
            if(b[i] > 1){
                if(!num[b[i]]){
                    flag = 1;
                    break;
                }
                else num[b[i]]--;
            }
        } 
 
        for(int i = 2; i < maxn; i++){
            if(num[i]){
                cnt += num[i];
            }
            if(cnt >= 2){
                flag = 1;
                break;
            }
        }
        //cout<<1;
        if(flag) puts("NO");
        else puts("YES");
    }
}   

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值