19级爪哇程序设计新手赛2.0(参考题解)

看完它

A - Candies CodeForces - 1343A
题意:

(1)玄学观察法,咋们先来看看案例:

3			--》	1				除以3==2^2-1
6			--》	2				除以3
7			--》	1				除以7==2^3-1
21			--》	7				除以3
28			--》	4				除以7
999999999	--》	333333333		除以3
999999984	--》	333333328		除以3

那么我们大胆推测答案是除以第一个整除它的 2x-1 后的那个数。
那我们交一发试试;结果:Accepted
(2)正规法:根据等比数列求和公式S=(a1-an*q)/(1-q)
在这里插入图片描述
上式变为 x * (2k-1)=n

枚举22-1,23-1,24-1,…,229-1,230-1

找到符合题意的x

#include <bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define db printf("where!\n");
#define pb push_back
using namespace std;
#define ll long long
ll gcd(ll x,ll y){return y ? gcd(y,x%y) : x;}
template<class T>inline void read(T &res){
char c;T flag=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
 
int main()
{
    int t;read(t);
    while(t--){
        int n;read(n);
        for(int i=2;i<=n;i++){
            ll a=pow(2,i)-1;
            if(n%a==0){
                cout<<n/a<<endl;
                break;
            }
        }
    }
	return 0;
}

B - Balanced Array CodeForces - 1343B
题意:n/2若为奇数,输出NO
因为,奇数个奇数和是奇数,奇数个偶数和是偶数,两者肯定不等。
n/2若为偶数,模拟如下

8
 
YES
2 4 6 8 1 3 5 11
 
数据生成过程如下
    2 4 6 8
    1 3 5 8+(1+1+1)=11
(1+1+1)的由来
2-1=1
4-3=1
6-5=1
共少了3个1
#include <bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define db printf("where!\n");
#define pb push_back
using namespace std;
#define ll long long
ll gcd(ll x,ll y){return y ? gcd(y,x%y) : x;}
template<class T>inline void read(T &res){
char c;T flag=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
 
int main()
{
    int t;read(t);
    while(t--){
        int n;read(n);
        if(n%4) cout<<"NO"<<endl;
        else{
            cout<<"YES"<<endl;
            for(int i=2;i<=n;i+=2) cout<<i<<" ";
            for(int i=1;i<n/2;i+=2) cout<<i<<" ";
            for(int i=n/2+3;i<n;i+=2) cout<<i<<" ";
            cout<<n+1<<endl;
        }
    }
	return 0;
}

C - Alternating Subsequence CodeForces - 1343C
题意:
给出一个序列,找到一个循环序列使得他们的和最大。
把每段连续的奇偶分段找出每一段的最大值相加即可

#include <bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define db printf("where!\n");
#define pb push_back
using namespace std;
#define ll long long
ll gcd(ll x,ll y){return y ? gcd(y,x%y) : x;}
template<class T>inline void read(T &res){
char c;T flag=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
int a[200005];
int main()
{
    int t;read(t);
    while(t--){
        int n;read(n);
        for(int i=1;i<=n;i++) read(a[i]);
        ll ans=0;
        for(int i=1;i<=n;){
            if(a[i]>0){
                int ma=a[i];
                while(a[i]>0) {
                    ma=max(ma,a[i]),i++;
                    if(i==n+1) break;
                }
                ans+=ma;
            }
            else {
                int mi=a[i];
                while(a[i]<0) {
                    mi=max(mi,a[i]),i++;
                    if(i==n+1) break;
                }
                ans+=mi;
            }
        }
        cout<<ans<<endl;
    }
	return 0;
}

D - 最小长方形 HDU - 1859
题意:
给你多个二维平面中点的坐标(x,y)(x、y都为整数),求一个最小长方形,要求所有给出的点都被它框在内部.所求长方形的边分别平行于x轴和y轴,落在边上的点也算是长方形在框内.

直接分别找到最大和最小就可以。

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
using namespace std;

int main(void)
{
      int a,b;
      while(cin>>a>>b){
            if(a==b&&a==0) break;
            int aa,bb;
            int ma1=a,ma2=b,mi1=a,mi2=b;
            while(cin>>aa>>bb){
                  if(aa==bb&&aa==0) break;
                  ma1=max(ma1,aa);
                  ma2=max(ma2,bb);
                  mi1=min(mi1,aa);
                  mi2=min(mi2,bb);
            }
            cout<<mi1<<" "<<mi2<<" "<<ma1<<" "<<ma2<<endl;
      }
      return 0;
}

E - Divisibility CodeForces - 630J

#include <bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#include <bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define db printf("where!\n");
#define pb push_back
using namespace std;
#define ll long long
template<class T>inline void read(T &res){
char c;T flag=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}

int main()
{
    ll n;cin>>n;
    ll k=1;
    for(ll i=2;i<=10;i++ ) k=i*k/__gcd(k,i);
    cout<<n/k;
    return 0;
}

F - Wrong Subtraction CodeForces - 977A
直接模拟

#include <bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define db printf("where!\n");
using namespace std;
#define ll long long
template<class T>inline void read(T &res){
char c;T flag=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}

int main()
{
    int n,k;cin>>n>>k;
    while(k--){
        if(n%10==0) n/=10;
        else n--;
    }
    cout<<n;
    return 0;
}

G - 最少拦截系统 HDU - 1257
思路:每次拿到一个值,判断他与前面的下降子序列中的最小值最接近的那个序列,然后把那个序列的最小值更新,如果前面的下降子序列的最小值没有比这个值大的,就另开数组把他当成一个新的子序列的起点。

最大上升子序列问题。可以动态规划解决。(可以自己去Submit一下)
下面代码的寻找过程可以二分优化,变成O(n logn)

#include <stdio.h>
#include <iostream>
using namespace std;
int a[30010];
int main ()
{
    int n,m;
    while (scanf ("%d",&n) != EOF){
       int i =1;
       int j;
       a[0]=33330;
       for (int k=0;k<n;k++){
           cin>>m;
           for (j=0;j<=i;j++){	//就是这里可以二分优化
               if ( a[j]>=m ){
                   a[j]=m;
                   break;
               }
           }
           if (j>i)
               a[++i] = m;
       }
       printf("%d\n",i);
    }
    return 0;
}

H - Rightmost Digit HDU - 1061
看完这道题,应该能够手鲁快速幂了吧。不知道的在这里一定要去学习一下,

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
using namespace std;

int main(void)
{
      int n;
      cin>>n;
      while(n--){
            int k;cin>>k;
            int num=1;
            int x=k%10;
            int y=k;
            while(y){
                  if(y%2==1) num=(num*x)%10;
                  x=(x*x)%10;
                  y/=2;
            }
            cout<<num*x%10<<endl;
      }
      return 0;
}

I - Parencodings POJ - 1068
在这里推荐大家去搜其他人的博客看看吧,行的话揣摩一下我的代码(其实是我已经忘记了当时的思路了,再想我今晚就失眠了),我已经写不下去了,我要睡觉了(累~~)
在这里插入图片描述
这么晚了,明天有事。

#include <iostream>
#include <algorithm>
#include <iomanip>
#include"stdio.h"
#include <cstring>
#include<math.h>
#include<map>
#include<queue>
#include<stack>
#include"time.h"
#define ll long long
#define MAX_INT  ((unsigned)(-1)>>1)
using namespace std;
int read()
{
    int c=0;int flag=1;
    char s;
    while((s=getchar())>'9'||s<'0')if(s=='-')flag=-1;
    c=s-'0';
    while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
    return c*flag;
}
int a[10005],p[25],w[25];
int main(void)
{
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        for(int i=1;i<=n;i++) cin>>p[i];
        memset(a,0,sizeof a);
        memset(w,0,sizeof w);
        int k=1;
        for(int i=1;i<=n;i++){
            for(int j=0;j<p[i]-p[i-1];j++) a[k++]=1;//左1 右0
            k++;
        }
        int c=1;
        for(int i=1;i<k;i++){
            if(a[i]==0){
                int num=1;
                for(int j=i-1;j>0;j--){
                    if(a[j]==1) num--,w[c]++;
                    else num++;
                    if(num==0){
                         c++;
                         break;
                    }
                }
            }
        }
        for(int i=1;i<n;i++){
            cout<<w[i]<<" ";
        }
        cout<<w[n]<<endl;
    }
    return 0;
}

彩蛋

写在后面吧,当你浏览完后,希望你已经解决了上面的问题。
想对你们说吧!部落真的是一个好地方,里面有优秀的师兄师姐(除了我)
不知道大家为什么会选择广金哈哈哈,我觉得选择广金或者广财的计算机相关的专业的同学都是看学校选专业的,而不是看专业选学校的。已经选择了这一个专业并且你已经接触了这么久算法了,我觉得你下学期的数据结构和大二下的算法课这两门课已经可以稳过了。
为什么要叫你珍惜好这次机会,因为这里有师兄师姐在你们前面带着你们前进,实时上,你们的实力肯定要增长得比我们快多了。可以这么说,有些师弟师妹的实力已经达到部落某些师兄师姐的水平了。(不是TA菜,而是你们进步得很快)
算法竞赛可能并不是每一个人都可以接受的,但既然你看到了这里,我还是希望你能够坚持下去。部落的算法组我们这一届是第二届,我们前两届的师兄师姐应该已经把坑差不多都踩得差不多了,所以你们以后集训的话可能会进步的更快。讲句真的,今年疫情这样,我们也不知道我们还能不能参加一次比赛,我们也没有参加正式acm过,这对我们这一届是非常的吃亏的,同样是努力一年多了,可能没有回报,这个损失是很巨大的。
选择了,就决定将它做好吧。希望你能够成为下一届大佬。加油!!!

可能深夜才会写这么多文绉绉的东西吧。该睡觉了。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值