1 条题解

  • 0
    @ 2025-8-24 22:40:02

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Aya_tt
    **

    搬运于2025-08-24 22:40:02,当前版本为作者最后更新于2022-09-24 15:19:44,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    这题我觉得是考验一些小技巧。

    如果一个一个枚举过去的时间,只能获得 6060 分。

    时限是 11 秒,所以我们就必须想着优化。那我们就是分模块讨论一下这道题目。

    11,枚举时间

    我们可以开个数组 aa 维护时间一位加一,如果等于十了,就进位,注意,第二位就是等于六的时候进位了。改进位的时候进位,值得注意的是十二点五九分后面是一点,需要特判。

    22,优化

    正如我们前面所说,直接一个个枚举时间,是不足已通过此题的,于是我们就想到了时间是循环的,一个循环是 720720 分钟,我们可以用我们暴力的程序,跑出发现一天是有 3131 个等差数列,所以在我们程序在跑之前,可以先看看过去了几天,然后就加上几天个 3131,之后再取余,跑一遍我们的暴力程序,此时,我们最坏查询的时间复杂度也接近线性,足以通过此题。

    33,代码实现

    #include<bits/stdc++.h>
    using namespace std;
    int a[5] = {0,1,2,0,0},Q;
    long long ans;
    int main(){
    	cin >> Q;
    	while(Q--){
    		int n;
    		cin >> n;
    		int l = n / 720;
    		ans += l * 31;
    		n %= 720;
    		for(register int i = 1;i <= n;i++){
    			a[4]++;
    			if(a[4] == 10){
    				a[4] = 0;
    				a[3]++;
    				if(a[3] == 6){
    					a[3] = 0;
    					a[2]++;
    					if(a[2] == 3 && a[1] == 1){
    						a[1] = 0;
    						a[2] = 1;
    					}
    					if(a[2] == 10){
    						a[1]++;
    						a[2] = 0;
    					}
    				} 
    			}
    			if(a[1] == 0){
    				if(a[4] - a[3] == a[3] - a[2]){
    					//cout<<a[1]<<" "<<a[2]<<" "<<a[3]<<" "<<a[4]<<endl;
    					ans++;
    				}
    			}
    			else if(a[4] - a[3] == a[3] - a[2] && a[2] - a[1] == a[3] - a[2]){
    				//cout<<a[1]<<" "<<a[2]<<" "<<a[3]<<" "<<a[4]<<endl;
    				ans++;
    			}
    		}
    		cout<<ans<<endl;
    		ans = 0;
    		a[1] = 1,a[2] = 2,a[3] = 0,a[4] = 0;//一定要清零!!
    	}	
    }
    
    • 1

    信息

    ID
    8056
    时间
    1000ms
    内存
    128MiB
    难度
    2
    标签
    (无)
    递交数
    0
    已通过
    0
    上传者