zoukankan      html  css  js  c++  java
  • 程序设计思维与实践 CSP-M2 补题 (3/4/数据班)

    程序设计思维与实践 CSP-M2 补题 (3/4/数据班)

    A - HRZ 的序列

    问题分析

    题意是,序列最多由三种不同的数字的构成。当由三种数字构成时,要求这三个数排序后构成等差数列;而由两种或一种数字构成时,直接成立。

    可以用STL种的set,遍历序列,每个数都加入集合中,如果集合的size大于3,不成立,输出“NO”,其他情况下,用迭代器,取出每种数字,放入数组排序。三个数字的话,必须是等差数列才输出“YES”,否则输出“NO”。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int main(){
    	ll a;
    	int t,n;
    	scanf("%d",&t);
    	while(t--){
    		scanf("%d",&n);
    		set<ll>s;
    		while(n--){
    			scanf("%lld",&a);
    			s.insert(a);
    		}
    		int var=s.size();
    		switch(var){
    			case 0:{
    				return -1;
    				break;
    			}
    			case 1:{
    				printf("YES
    ");
    				break;
    			}
    			case 2:{
    				printf("YES
    ");
    				break;
    			}
    			case 3:{
    				ll a[3];
    				int i=0;
    				set<ll>::iterator iter;
    				for(iter=s.begin();iter!=s.end();++iter){
    					a[i++]=*iter;
    				}
    				sort(a,a+i);
    				if(a[1]-a[0]==a[2]-a[1]){
    					printf("YES
    ");
    				}
    				else{
    					printf("NO
    ");
    				}
    				break;
    			}
    			default:{
    				printf("NO
    ");
    				break;
    			}
    		}
    	}
    	return 0;
    } 
    
    

    B - HRZ 学英语

    问题分析

    从首字母开始,对一个长度为26的序列进行判定。

    要求每个大写字母出现0次或者1次,每一段里面,要求大写字母和“?”的数目和为26。

    输出的时候,从前往后,依次输出,可以保证字典序最小。

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	string str;
    	cin>>str;
    	int l=0,r=25;
    	int len=str.length();
    	while(r<len){
    		int letter[27]={};
    		int p=l;
    		while(p<=r){
    			if(str[p]=='?'){
    				letter[26]++;
    			}
    			else{
    				letter[str[p]-'A']++;
    				if(letter[str[p]-'A']>1){
    					break;
    				}
    			}
    			p++;
    		}
    		p--;
    		if(p==r){
    			int index=0;
    			int i=l;
    			while(i<=r){
    				if(str[i]!='?'){
    					cout<<str[i];
    				}
    				else{
    					while(letter[index]!=0){
    						index++;
    					}
    					cout<<(char)('A'+index);
    					index++;
    				}
    				i++;
    			}
    			return 0;
    		}
    		l++;
    		r++;
    	}
    	cout<<"-1"<<endl;
    	return 0;
    }
    

    C - 咕咕东的奇妙序列

    问题分析

    错解:一开始认为题目考察数列的通项公式,直接写出了以下代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    void Query(ll n)
    {
    	ll group=0;
    	while(group*(group+1)/2<n){
    		group++;
    	}
    	group--;
    	n-=(group*(group+1)/2);
    	printf("%lld
    ",n);
    }
    int main()
    {
    	ll n;
    	ll d;
    	scanf("%lld",&n);
    	while(n--){
    		scanf("%lld",&d);
    		Query(d);
    	}
    	return 0;
    } 
    

    这段代码,是求某个数的索引的,但是,题目要求的“数”,指的是数字,例如...11 12 13
    这些,按照上述代码求,认为是三个数,事实上题目认为这是六个数字。

    正解:有多种理解方式,很多人理解为一个由数字构成的梯形,这样就比较直观了。

    关键还是确定每组数的数量。

    例如,某一组有{11}{12}{13},这认为是三项,每项里还有两个数。求整个数列的第n个数,容易确定属于哪一个“组”,求这一组的第i个数,再确定它属于哪一“项”。之前的代码虽然是错的,仍然对解题有贡献。

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
     
    void Work() {
        LL n;
        scanf( "%lld", &n );
        LL LastLen = 0, Len, Count;
        for( Len = 1; ; ++Len ) {
            Count = 9;
            for( LL i = 1; i < Len; ++i ) 
                Count = Count * 10;
            LL Sum = ( LastLen + Len + LastLen + Count * Len ) * Count / 2;
            if( n <= Sum ) break;
            n -= Sum;
            LastLen += Count * Len;
        }
        LL Left = 1, Right = Count, Mid, Ans;
        while( Left <= Right ) {
            Mid = ( Left + Right ) >> 1;
            LL Sum = ( LastLen + Len + LastLen + Mid * Len ) * Mid / 2;
            if( Sum >= n ) {
                Ans = Mid;
                Right = Mid - 1;
            } else Left = Mid + 1;
        }
        --Ans;
        n -= ( LastLen + Len + LastLen + Ans * Len ) * Ans / 2;
        ++Ans;
        for( Len = 1; ; ++Len ) {
            Count = 9;
            for( LL i = 1; i < Len; ++i ) 
                Count = Count * 10;
            LL Sum = Count * Len;
            if( Sum >= n ) break;
            n -= Sum;
        }
        LL Num = ( n + Len - 1 ) / Len;
        n = n - ( Num - 1 ) * Len;
        LL T = 1;
        for( LL i = 1; i < Len; ++i ) T = T * 10;
        Num = T + Num - 1;
        T = Len - n + 1;
        for( LL i = 1; i < T; ++i ) Num = Num / 10;
        printf( "%lld
    ", Num % 10 );
        return;
    }
     
    int main() {
        LL Query;
        scanf( "%lld", &Query );
        for( LL i = 1; i <= Query; ++i ) Work();
        return 0;
    }
    
    
  • 相关阅读:
    ie6下使PNG背景图片透明的方法
    CSS图片转换成模糊(毛玻璃)效果兼容版
    对象Object下的属性和方法
    Collection 回顾
    Java IO学习笔记:File类
    Android开发之Instrumentation(自动化测试)
    Android开发之ActivityManager
    Android开发之WindowManager详解
    在Intel® Galileo Gen 2开发板上运行Debian操作系统
    VS2008下安装与配置DirectShow SDK 9.0
  • 原文地址:https://www.cnblogs.com/master-cn/p/12726214.html
Copyright © 2011-2022 走看看