• luoguP1871 对撞机【赛后第一题


    题面

    题目描述
    在2312年,宇宙中发现了n台巨型对撞机,这些对撞机分别用1-n的自然数标识。科学家们不知道启动这些对撞机会发生什么危险事故,所以这些机器,刚开始都是出于关闭的状态。

    随着科学家们的研究发现,第i台对撞机启动是安全的,如果其他已经启动的对撞机的标识数都跟着台对撞机标识数互质。(例如假设前面启动的是j,如果i能启动,那么i,j互质,也就是i,j的最大公约数为1)。如果两台对撞机不互为质数就启动,那么就会发生爆炸事故。

    基于前面的研究,科学家们准备做各种启动和关闭对撞机的实验。为了确保科学家们的生命安全,你要设计一个远程遥控的软件。

    刚开始,所有的额对撞机都是关闭状态。你的程序将会收到许多询问,格式为“启动、关闭第i台对撞机”。这个程序应该能处理这些询问(根据收到询问的先后顺序处理)。程序按照如下的格式输出处理结果。

    如果询问时“+i”(表示第i台对撞机启动),这程序应该按照下面三种的情况之一输出结果。

    (1)“Success”,表示启动第i台是安全的。

    (2)“Already on”,表示第i台在询问之前就已经启动了。

    (3)“Conflict with j”,如果第i台隔年面启动了的第j台冲突,就不能启动第i;如果前面有多台跟i冲突,那么只输出其中任何一台即可。

    如果寻味是“-i”(表示关闭第i台对撞机),这程序应该按照下面两种情况之一输出结果。

    (1)“Success”,表示关闭第i台对撞机

    (2)“Already off”,表示第i台对撞机在询问之前就已经关闭了。

    输入格式
    第一行输入两个空格隔开的整数n和m(1<=n,m<=10^5),分别表示对撞机的数量和询问数。

    接下来m行,表示询问,每行要么为“+ i”,要么为“- i”(不含引号)(1<=i<=n)。

    输出格式
    输出m行,输出结果按照上面题目给定格式输出。

    输入输出样例
    输入 #1
    10 10

    • 6
    • 10
    • 5
    • 10
    • 5
    • 6
    • 10
    • 3
    • 6
    • 3
      输出 #1
      Success
      Conflict with 6
      Success
      Already off
      Success
      Success
      Success
      Success
      Conflict with 3
      Already on

    分析

    这是我的csp2019考砸后的第一题, 认识到自己以前的不足之后,决定,以后博文里都写题面,不再写题意

    我们都需要一个好好思考的过程!
    进入正题:

    这是一道很好的理解分解质因数的题目, 其实思路挺好想的, 就是有些细节要注意
    细节, 易错点收录在首页轮播第四个“精选傻X错误”中, 这里先贴上代码(很丑, 勿喷

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int N = 100000+99;
    inline int read() {
    	char ch = getchar(); int x = 0;
    	while(ch<'0' || ch>'9') {ch = getchar();}
    	while(ch>='0' && ch<='9') {x = (x<<1)+(x<<3)+(ch^48); ch = getchar();}
    	return x;
    }
    
    int n, m;
    int not_prime[N];
    int prime[N], tot, mn_prime[N];
    void L_S() {
    	mn_prime[1] = 1;
    	for(int i = 2; i <= n; i++) {
    		if(not_prime[i] == 0) {
    			mn_prime[i] = i;
    			prime[++tot] = i;
    		}
    		for(int j = 1; j <= tot && i*prime[j] <= n; j++) {
    			not_prime[i*prime[j]] = 1;
    			mn_prime[i*prime[j]] = prime[j];
    			if(i%prime[j] == 0) break;
    		}
    	}
    }
    
    char cmd;
    int id, tmp, is, mnprime;
    int a[N];//记录每个数是隶属于哪个数(为0表示没有选 
    int main() {
    	n = read(), m = read();
    	L_S();
    //	for(int i = 1; i <= n; i++) printf("%d ", mn_prime[i]);
    	for(int i = 1; i <= m; i++) {
    		cin>>cmd; id = read();
    		if(id == 1) {
    			if(cmd == '+') {
    				if(a[1] == 1) printf("Already on
    ");
    				else printf("Success
    ");
    				a[1] = 1;
    			}else {
    				if(a[1] == 0) printf("Already off
    ");
    				else printf("Success
    ");
    				a[1] = 0;
    			}
    			continue;
    		}
    		if(cmd == '+') {
    			if(a[id] != id) {
    				tmp = id;
    				is = 1;
    				while(tmp > 1) {//判断它的质因数是否已经被选
    					if(a[mn_prime[tmp]]) {
    						is = 0;
    						printf("Conflict with %d
    ", a[mn_prime[tmp]]);
    						break;
    					}
    					mnprime = mn_prime[tmp];
    					while(tmp && tmp%mnprime == 0) tmp /= mnprime;//.........
    				}
    				if(is) {
    					tmp = id;
    					while(tmp > 1) {//用相同的方法把质因数都打上标记 
    						a[tmp] = id;
    //						printf("a[%d] = %d
    ", tmp, id);
    						mnprime = mn_prime[tmp];
    						while(tmp && tmp%mnprime == 0) tmp /= mnprime;
    						a[mnprime] = id;//别忘了去掉的质数要在这里处理,下面也是 
    					}
    					printf("Success
    ");
    				}
    			}else printf("Already on
    ");
    		}else {
    			if(a[id] != id) printf("Already off
    ");
    			else {
    				while(id > 1) {
    					a[id] = 0;
    					mnprime = mn_prime[id];
    					while(id && id%mnprime == 0) id /= mnprime;
    					a[mnprime] = 0;
    				}
    				printf("Success
    ");
    			}
    		}
    	}
    }
    
  • 相关阅读:
    OSI模型白话
    并发
    初始化与清理
    多线程
    recyclerview Adapter
    recyclerview刷新
    surfaceview
    viewgroup绘制流程
    view配置
    项目遇到的问题
  • 原文地址:https://www.cnblogs.com/tyner/p/12024061.html
Copyright © 2020-2023  润新知