• [泉州4月月赛]


    开始被毒瘤数据卡了几个点,没有一下\(AK\)

    \(A\)
    考虑答案为\(n - \lfloor n / x \rfloor\)

    A
    #include<iostream>
    #include<cstdio>
    #define ll long long
    
    inline ll abs(ll x){
      return (x < 0) ? -x : x;
    }
    
    int main(){
      ll n,x;
      scanf("%lld%lld",&n,&x);
      if(x == 0)
      puts("0");
      else
      std::cout<<n - n / abs(x)<<std::endl;
    }
    

    \(B\)

    倒序算就行了。

    B
    #include<iostream>
    #include<cstdio>
    #define ll long long
    #define N 1000005
    ll c[N];
    int main(){
      ll n,k;
      scanf("%lld%lld",&n,&k);
      for(int i = 1;i <= n;++i){
      	scanf("%lld",&c[i]);
      }
      for(int i = n;i >= 1;--i){
      	k -= c[i];
      	if(k <= 0){
      		std::cout<<i<<std::endl;
      		return 0;
      	}
      }
    }  
    

    \(C\)

    感性理解一下,答案是\(\sum_{x1}^{y1}a_i\sum_{x2}^{y2}b_i\)
    前缀和维护就好了

    C
    #include<iostream>
    #include<cstdio>
    #define ll long long
    #define N 1000005
    
    ll n,m;
    
    ll suma[N],sumb[N];
    
    int main(){
    	scanf("%lld%lld",&n,&m);
    	for(int i = 1;i <= n;++i){
    		ll x;
    		scanf("%lld",&x);
    		suma[i] = suma[i - 1] + x;
    	}
    	for(int i = 1;i <= m;++i){
    		ll x;
    		scanf("%lld",&x);
    		sumb[i] = sumb[i - 1] + x;
    	}
    	ll k;
    	scanf("%lld",&k);
    	while(k -- ){
    		ll x1,x2,y1,y2;
    		scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
    		std::cout<<(suma[x2] - suma[x1 - 1]) * (sumb[y2] - sumb[y1 - 1])<<std::endl;
    	}
    }
    

    \(D\)
    对于非负数,直接输出他的整数部分。
    对于负数,如果小数部分是\(.000\)或者是整数,直接输出,否则把整数部位\(-1\)

    D
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long 
    #define N 10000005
    
    char s[N];
    ll p = 0,k = 0;
    ll num[N];
    
    int main(){
    	scanf("%s",s + 1);
    	for(int i = 1;i <= strlen(s + 1);++i)
    	if(s[i] == '.')
    	p = i;
    	if(!p)
    	std::cout<<s + 1;
    	else{
    		if(s[1] != '-'){
    		for(int i = 1;i <= strlen(s + 1);++i){
    		if(s[i] != '.')
    		std::cout<<s[i];
    		else
    		break;
    		}
    		}else{
    			for(int i = p + 1;i <= strlen(s + 1);++i)
    			if(s[i] != '0')
    			k = i;
    			if(k){
    			ll pr = 0;
    			for(int i = 2;i < p;++i)
    			num[i - 1] = s[i] - '0';
    			num[p - 2] += 1;
    			pr = num[p - 2] / 10;
    			num[p - 2] = num[p - 2] % 10; 
    			for(int i = p - 3;i >= 1;--i){
    				num[i] += pr;
    				pr = num[i] / 10;
    				num[i] = num[i] % 10;
    			}
    			std::cout<<"-";
    			if(pr)
    			std::cout<<pr;
    			for(int i = 1;i <= p - 2;++i)
    			std::cout<<num[i];
    			}else{
    				for(int i = 1;i < p;++i)
    				std::cout<<s[i];
    			}
    		}
    	}
    }
    
    

    \(E\)
    我们发现我们只要对一堆的答案确定,那么可以计算出总答案。
    我们用可达性\(01\)背包,算出有哪些值可以平凑出来就好。
    注意有负值,所以考虑全部数向上移。
    注意不要越界。

    E
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<map>
    #define ll long long 
    #define N 2005
    
    ll n;
    ll num[N],sum,ans,maxx,minn;
    bool QWQ[N * 2000];
    
    int main(){
    	scanf("%lld",&n);
    	for(int i = 1;i <= n;++i){
    		scanf("%lld",&num[i]),sum += num[i];
    		if(num[i] > 0)
    		maxx += num[i];
    		else
    		minn -= num[i];
    	}
    	QWQ[minn + 1000] = 1;
    	for(int i = 1;i <= n;++i){
    		for(int s = maxx + minn + 1000;s >= -2 * minn;--s){
    			if(s + num[i] + minn + 1000 >= 0)
    			if(!QWQ[s + num[i] + minn + 1000] && QWQ[s + minn + 1000]){
    				QWQ[s + num[i] + minn + 1000] = QWQ[s + minn + 1000];
    				ans = std::max(ans,(s + num[i]) * (sum - s - num[i]));
    			}
    		}
    	}
    	std::cout<<ans<<std::endl;
    }
    
    

    \(F\)
    因为是连续的一串数字。
    所以我们只要考虑一个数字就好。
    对于一个数字处理出他在哪里出现过。
    那么让两个相同数字的位置相邻的代价是消除两个位置中所有的数字。
    维护一下消除代价的前缀和,那么对于一个位置,他的答案是最大的到他位置的代价小于\(k\)的长度。
    指针维护一下。
    复杂度\(O(n)\)
    考虑分析,每个数字只会走一遍。

    F
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #define ll long long
    #define N 200005
    
    ll n,m,k;
    
    std::vector<int>QWQ[N];
    ll sum[N],ans = 1;
    
    int main(){
    	scanf("%lld%lld%lld",&n,&m,&k);
    	for(int i = 1;i <= n;++i){
    		ll x;
    		scanf("%lld",&x);
    		QWQ[x].push_back(i); 
    	}	
    	for(int i = 1;i <= m;++i){
    		for(int j = 1;j <= QWQ[i].size();++j)
    		sum[j] = 0;
    		for(int j = 0;j < QWQ[i].size();++j){
    			sum[j + 1] = sum[j] + QWQ[i][j + 1] - QWQ[i][j] - 1; 
    		}
    		ll l = 0;
    		for(int j = 1;j < QWQ[i].size();++j){
    			while(sum[j] - sum[l] > k)
    			l ++ ;
    			ans = std::max(ans,j - l + 1);
    		}
    	}
    	std::cout<<ans<<std::endl;
    }
    
  • 相关阅读:
    crontab 移动日志-超越昨天的自己系列(12)
    java进程性能分析步骤-超越昨天的自己系列(11)
    Linux 使用 you-get 指令下载网页视频
    Git git rm和git rm --cached
    Git .gitignore中已添加文件路径,但仍未被忽略
    Android 系统添加SELinux权限
    git 删除目录及子目录下的同名文件
    Android 查看和修改网络mtu
    git 设置git用户名和邮箱,并生成秘钥
    RK3288 添加普通串口uart1和uart3
  • 原文地址:https://www.cnblogs.com/dixiao/p/14674101.html
Copyright © 2020-2023  润新知