QFNU-ACM 2020.10.30 Trating

D.

题意:给定一个字符串,0表示一个航天公司、1表示另外一个航天公司、同一个航天公司的飞机免费,问从a到b最少花费的价钱是多少。

题解:这是一个cf的a题,主要是思维,因为不论怎样从0的旁边都有1,1的旁边都有0,所以最少价钱是0,最多价钱就是1,还是cf打的太少了。

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,a,b;
    string p;
    cin>>n>>a>>b;
    cin>>p;
    if(p[a-1]==p[b-1]){
        cout<<0<<endl;
    }
    else{
        cout<<1<<endl;
    }
}

E.

题意:给定一个执行n-1次的序列,执行一次就多加一个数然后把序列加到前面,问第k的数是多少。

题解:根据题目给定的范围是一个找规律的题目,

初态: 1 此时 n=1

第 1 次: 1 2 1 此时 n=2

第 2 次: 1 2 1 3 1 2 1 此时 n=3

第 3 次: 1 2 1 3 1 2 1 4 1 2 1 3 1 2 此时 n=4

…………

以上可以看出:

序列的奇数位置均为 1;

序列的偶数位置,可以观察:出现同一个数字的位置成等差数列

第一次出现 2 的位置是 2 ^ ( 2-1 ) ,公差为 2 ^ 2 ;

第一次出现 3 的位置是 2 ^ ( 3-1 ) ,公差为 2 ^ 3 ;

第一次出现 4 的位置是 2 ^ ( 4-1 ) ,公差为 2 ^ 4 ;

…………

第一次出现 m 的位置是 2 ^ ( m-1 ) ,公差为 2 ^ m ;通项公式为 ( 2t - 1 ) * 2 ^ ( m -1 ) ,表示第 t 次出现 m 的位置是 ( 2t - 1 ) * 2 ^ ( m -1 ) ;这里的 t = ( 1,2,3 …… ) ,显然 t 为奇数。

处理 n-1 次出现的整数有 n 个,然后枚举这 n 个整数,判断是否合法。

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#define LL long long
using namespace std;
int n;
LL k;
int main()
{
    while(~scanf("%d%I64d",&n,&k))
    {
        if(k&1)
            puts("1");
        else
        {
            for(int i=1;i<=n;i++)
            {
                LL p=1LL<<i-1;
                if(k%p==0&&((k/p)&1))
                {
                    printf("%d\n",i);
                    break;    
                }    
            }
        }    
    }
    return 0;
} 

F.

题意:给一个公式然后给你一个n,问能否求得x、y、z。

 

题解:一个数学题,给了2/n就已经暗示了要把2/n拆成2个1/n,然后使得得x=1/n那么可以消得1/n=1/y+1/z了,根据数学公式1/(n+1)+1/n(n+1)等于1/n,所以y=(n+1),z=n(n+1),再特判下当n=1时不存在即可。

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main(){
    ll n;
    cin>>n;
    ll a,b,c;
    a=n;
    b=n+1;
    c=n*(n+1);
    if(n==1){
        cout<<-1<<endl;
        return 0;
    }
    cout<<a<<" "<<b<<" "<<c<<endl;
}

 7-6 连续因子 (20分)

题意:找出最长的连续因子,并输出最小的那个。

题解:遍历从2-根号n,然后只要能被模就进行判断,最大的因子是几个,一直循环判断,然后最后输出最大的就行。

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main(){
    ll n,sum=0,k;
    cin>>n;
    for(ll i=2;i*i<=n;i++){
        if(n%i!=0){
            continue;
        }
        ll j=i;
        ll t=n;
        ll num=0;
        while(t%j==0){
            t/=j;
            j++;
            num++;
        }
        if(sum<num){
            sum=num;
            k=i;
        }
    }
    if(sum==0){
        cout<<1<<endl;
        cout<<n<<endl;
    }
    else{
        cout<<sum<<endl;
        for(int i=0;i<sum;i++){
            if(i!=sum-1){
                cout<<k+i<<"*";
            }
            else{
                cout<<k+i<<endl;
            }
        }
    }
} 

7-5 古风排版 (20分)

题意:就是像古人一样从右到左从上到下输出。

题解:比赛的时候就是这题卡着心态崩了,想到了好多方法就是一直错了,其实就是用一个一维数组,找出n然后输从后往前输出然后--n输出。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;


int main()
{
    int n;
    cin>>n;
    getchar(); 
    
    char a[1155];
    cin.get(a,1155); //输入带有空格的字符串
  
    int num=strlen(a); //cout<<num;
    int num1;
    int sub=(num/n);  //num是长度,n是每列n个字符 
    if(num%n!=0)
    {
        sub++;
        num1=sub*n;   //sub是 
     
     
         for(int i=num;i<num1;i++)
    {
        a[i]=' ';
    }
    sub--;
    for(int j=n;j>0;j--)
    {
    for(int i=num1-j;i>=0;i=i-n)
    {
        cout<<a[i];
    }
    cout<<endl;
    }
    }
    else
    {
            for(int j=n;j>0;j--)
        {
        for(int i=num-j;i>=0;i=i-n)
        {
        cout<<a[i];
        }
        cout<<endl;
        }
    }
}

 

posted @ 2020-11-07 14:40  liyongqishiwo  阅读(113)  评论(0编辑  收藏  举报