码迷,mamicode.com
首页 > 其他好文 > 详细

焦作选拔赛题解

时间:2018-10-10 23:44:42      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:智商   bsp   重载   控制   题目   手写   fst   tar   cos   

比赛题解  部分题目较难

阴阳链

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <bits/stdc++.h>
#define maxn 100005
using namespace std;
int dp[maxn];
int de[maxn];
int a[maxn];
int f[2][maxn];
int main()
{
    int n;
    while(cin>>n)
    {
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            f[0][i]=i;
            f[1][i]=i;
        }
        int maxs=0,x,z=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=i-1;j>=1;j--)
            {
                if(a[i]>a[j]&&dp[i]<=de[j]+1)
                {
                    dp[i]=de[j]+1;
                    f[0][i]=j;
                }

                if(a[i]<a[j]&&de[i]<=dp[j]+1)
                {
                    de[i]=dp[j]+1;
                    f[1][i]=j;
                }
            }
            if(dp[i]>maxs)
            {
                maxs=dp[i];
                x=i;
                z=0;
            }
            if(de[i]>maxs)
            {
                maxs=de[i];
                x=i;
                z=1;
            }
           // cout<<dp[i]<<" "<<de[i]<<‘ ‘<<i<<‘ ‘<<a[i]<<endl;
        }
        /*
        for(int i=0;i<2;i++)
        {
            for(int j=1;j<=n;j++)
            {
                cout<<f[i][j]<<‘ ‘;
            }
            cout<<endl;
        }
        cout<<x<<endl;
        */

        while(1)
        {
            cout<<a[x]<< ;
            if(f[z][x]==x) break;
            x=f[z][x];
            z=!z;
        }
        cout<<endl;
    }
}

 

归去来兮何由征 

手写堆

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdlib>
#include <ctime>
#include <fstream>
struct aaa{int l,r,x;}aa[300003],bb[300001];
int t=0,a[300003],b[300003],l[300003],r[300003],c[300003];

bool panduan(int x,int y)
{
    if(aa[x].x>aa[y].x||(aa[x].x==aa[y].x&&aa[x].l<aa[y].l))return 1;
    return 0;
}
void gouzao(int v)
{
    if(v==1)return;
    if(panduan(v,v/2))std::swap(aa[v],aa[v/2]),gouzao(v/2);
}
void xiugai(int v)
{
    if(v*2>t)return;
    if(v*2==t){if(panduan(v*2,v))std::swap(aa[v],aa[v*2]);return;}
    if(!panduan(v*2,v)&&!panduan(v*2+1,v))return;
    if(panduan(v*2,v*2+1))std::swap(aa[v],aa[v*2]),xiugai(v*2);
    else std::swap(aa[v],aa[v*2+1]),xiugai(v*2+1);
}
int main()
{

    int n,t1=0;
    std::string s;
    std::cin>>n>>s;

    for(int i=1;i<=n;i++)
    {
        std::cin>>a[i];
        if(s[i-1]==X)b[i]=1;
    }


    for(int i=1;i<n;i++)
    {
        l[i]=i-1,r[i]=i+1;

        if(b[i]==b[i+1])continue;
        aa[++t].l=i,aa[t].r=i+1,aa[t].x=a[i]+a[i+1],gouzao(t);
    }
    l[n]=n-1,r[n]=0;
    while(t)
    {
        if(!c[aa[1].l]&&!c[aa[1].r])
        {
            int x=aa[1].l,y=aa[1].r;
            std::swap(aa[1],aa[t--]),xiugai(1);
            bb[++t1].l=x,bb[t1].r=y;

            c[x]=c[y]=1;
            int x1=l[x],y1=r[y];

            if(!x1||!y1)continue;
            else
            {
                r[x1]=y1,l[y1]=x1;
                if(b[x1]!=b[y1])aa[++t].l=x1,aa[t].r=y1,aa[t].x=a[x1]+a[y1],gouzao(t);
            }
        }
        else std::swap(aa[1],aa[t--]),xiugai(1);
    }
    std::cout<<t1<<std::endl;
    for(int i=1;i<=t1;i++)
    {
        std::cout<<bb[i].l<< <<bb[i].r<<std::endl;
    }
}

 

三角形

#include<bits/stdc++.h>
using namespace std;
int main(){
   int ans=0,z=0;
   for(int j=4;j<=1000;j++){
      int cnt=0;
      for(int k=1;k<j/2;k++){
        if(((j*j-2*j*k)%(2*j-2*k))==0){
           cnt++;
        }
      }
      if(cnt>z){
         ans=j;
         z=cnt;
      }
   }
   cout<<ans<<endl;
}

 

魔板

较难搜索

#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
#include<queue>
using namespace std; 
typedef long long LL;
const int N = 8;
queue <LL> que;
string ans[50000];
char str1[10], str2[10];
bool vis[50000];

int map[10];//映射
int num[10];
 
LL fac[N];//阶乘
void change(int s[], int o){//o分别是0,1,2,表示ABC三种变化
    switch(o){
        case 0:
            for(int i = 0; i < 4; i ++) swap(s[i], s[8-i-1]);
            break;
        case 1:
            for(int i = 3; i >= 1; i --) swap(s[i], s[i-1]);
            for(int i = 4; i < 7; i ++) swap(s[i], s[i+1]);
            break;
        case 2:
            swap(s[1], s[6]);
            swap(s[6], s[5]);
            swap(s[5], s[2]);    
            break;
    } 
} 
void cantor(int s[], LL num, int k){//康托展开,把一个数字num展开成一个数组s,k是数组长度
    int t;
    bool h[k];//0到k-1,表示是否出现过 
    memset(h, 0, sizeof(h)); 
    for(int i = 0; i < k; i ++){
        t = num / fac[k-i-1];
        num = num % fac[k-i-1];
        for(int j = 0, pos = 0; ; j ++, pos ++){
            if(h[pos]) j --;
            if(j == t){
                h[pos] = true;
                s[i] = pos + 1;
                break;
            }
        }
    }
}
void inv_cantor(int s[], LL &num, int k){//康托逆展开,把一个数组s换算成一个数字num 
    int cnt;
    num = 0;
    for(int i = 0; i < k; i ++){
        cnt = 0;
        for(int j = i + 1; j < k; j ++){
            if(s[i] > s[j]) cnt ++;//判断几个数小于它
        }
        num += fac[k-i-1] * cnt;
    }
}
void init(){
    fac[0] = 1;
    for(int i = 1; i < N; i ++) fac[i] = fac[i-1] * i;
    int a[8], b[8];
    LL temp, temp2;
    que.push(0);
    vis[0] = true;
    while(!que.empty()){
        LL temp = que.front(); que.pop();
        cantor(a, temp, 8);
        for(int i = 0; i < 3; i ++){
            copy(a, a+8, b);
            change(b, i);
            inv_cantor(b, temp2, 8);
            if(!vis[temp2]){
                que.push(temp2);
                vis[temp2] = true;
                ans[temp2] = ans[temp] + (char)(A + i);
            }
        }
    }
}
int main(){
    init();
    int T;std::cin>>T;
    while(T--){
        scanf("%s%s", str1,str2);
        //先把所有初始状态都转换成12345678
        //最终状态根据初始状态的转换而转换 
        //这样只要一次预处理就可以解决问题了 
        for(int i = 0; i < 8; i ++) map[str1[i] - 0] = i + 1;
        for(int i = 0; i < 8; i ++) num[i] = map[str2[i] - 0];
        LL temp;
        inv_cantor(num, temp, 8);
        cout << ans[temp] << endl;
    }
}

 

A easy problem

矩阵快速幂

#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#define maxn 6+5
#define clr(x,y) memset(x,y,sizeof(x))
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
const double pi = acos( -1 );
//const ll mod = 1e9+7;

int a[10];
ll k,m;
ll qmul(ll a,ll b)
{
     ll ans=0;
    while(b)
    {
        if(b&1)ans=(ans+a)%m;
        a=(a+a)%m;
        b>>=1;
    }
    return ans;
}
struct matrix
{
    int n;
    ll maze[maxn][maxn];
    void init(int n)
    {
        this->n=n;
        clr(maze,0);
    }
    matrix operator * (matrix & rhs)
    {
        matrix ans;
        ans.init(n);
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                for(int k=0;k<n;k++)
                    ans.maze[i][j]=(ans.maze[i][j]+qmul(maze[i][k],rhs.maze[k][j]))%m;
        return ans;
    }
};
matrix qlow(matrix a,ll n)
{
    matrix ans;
    ans.init(a.n);
    for(int i=0;i<ans.n;i++)ans.maze[i][i]=1;
    while(n)
    {
        if(n&1)ans=ans*a;
        a=a*a;
        n>>=1;
    }
    return ans;
}
int main()
{
    //freopen("d:\\acm\\in.in","r",stdin);
    while(~scanf("%lld %lld",&k,&m))
    {
        for(int i=0;i<10;i++)
            scanf("%d",&a[i]);
        if(k<10)
        {
            printf("%lld\n",k%m);
            continue;
        }
        matrix ans;
        ans.init(10);
        for(int i=0;i<10;i++)ans.maze[0][i]=i;
        matrix ant;
        ant.init(10);
        for(int i=0;i<9;i++)ant.maze[i+1][i]=1;
        for(int i=0;i<10;i++)ant.maze[i][9]=a[9-i];
        matrix tmp;
        tmp=qlow(ant,k-9);
        ans=ans*tmp;
        printf("%lld\n",ans.maze[0][9]);
    }
    return 0;
}

 

方程

#include <bits/stdc++.h>

using namespace std;
#define MAXN 9999
#define MAXSIZE 1010
#define DLEN 4
class BigNum
{
private:
    int a[500]; //可以控制大数的位数
    int len;
public:
    BigNum() {
        len=1;    //构造函数
        memset(a,0,sizeof(a));
    }
    BigNum(const int); //将一个int类型的变量转化成大数
    BigNum(const char*); //将一个字符串类型的变量转化为大数
    BigNum(const BigNum &); //拷贝构造函数
    BigNum &operator=(const BigNum &); //重载赋值运算符,大数之间进行赋值运算
    friend istream& operator>>(istream&,BigNum&); //重载输入运算符
    friend ostream& operator<<(ostream&,BigNum&); //重载输出运算符
    BigNum operator+(const BigNum &)const; //重载加法运算符,两个大数之间的相加运算
    BigNum operator-(const BigNum &)const; //重载减法运算符,两个大数之间的相减运算
    BigNum operator*(const BigNum &)const; //重载乘法运算符,两个大数之间的相乘运算
    BigNum operator/(const int &)const; //重载除法运算符,大数对一个整数进行相除运算
    BigNum operator^(const int &)const; //大数的n次方运算
    int operator%(const int &)const; //大数对一个int类型的变量进行取模运算
    bool operator>(const BigNum &T)const; //大数和另一个大数的大小比较
    bool operator>(const int &t)const; //大数和一个int类型的变量的大小比较
    void print(); //输出大数
};
BigNum::BigNum(const int b) //将一个int类型的变量转化为大数
{
    int c,d=b;
    len=0;
    memset(a,0,sizeof(a));
    while(d>MAXN) {
        c=d-(d/(MAXN+1))*(MAXN+1);
        d=d/(MAXN+1);
        a[len++]=c;
    }
    a[len++]=d;
}
BigNum::BigNum(const char *s) //将一个字符串类型的变量转化为大数
{
    int t,k,index,L,i;
    memset(a,0,sizeof(a));
    L=strlen(s);
    len=L/DLEN;
    if(L%DLEN)len++;
    index=0;
    for(i=L-1; i>=0; i-=DLEN) {
        t=0;
        k=i-DLEN+1;
        if(k<0)k=0;
        for(int j=k; j<=i; j++)
            t=t*10+s[j]-0;
        a[index++]=t;
    }
}
BigNum::BigNum(const BigNum &T):len(T.len) //拷贝构造函数
{
    int i;
    memset(a,0,sizeof(a));
    for(i=0; i<len; i++)
        a[i]=T.a[i];
}
BigNum & BigNum::operator=(const BigNum &n) //重载赋值运算符,大数之间赋值运算
{
    int i;
    len=n.len;
    memset(a,0,sizeof(a));
    for(i=0; i<len; i++)
        a[i]=n.a[i];
    return *this;
}
istream& operator>>(istream &in,BigNum &b)
{
    char ch[MAXSIZE*4];
    int i=-1;
    in>>ch;
    int L=strlen(ch);
    int count=0,sum=0;
    for(i=L-1; i>=0;) {
        sum=0;
        int t=1;
        for(int j=0; j<4&&i>=0; j++,i--,t*=10) {
            sum+=(ch[i]-0)*t;
        }
        b.a[count]=sum;
        count++;
    }
    b.len=count++;
    return in;
}
ostream& operator<<(ostream& out,BigNum& b) //重载输出运算符
{
    int i;
    cout<<b.a[b.len-1];
    for(i=b.len-2; i>=0; i--) {
        printf("%04d",b.a[i]);
    }
    return out;
}
BigNum BigNum::operator+(const BigNum &T)const //两个大数之间的相加运算
{
    BigNum t(*this);
    int i,big;
    big=T.len>len?T.len:len;
    for(i=0; i<big; i++) {
        t.a[i]+=T.a[i];
        if(t.a[i]>MAXN) {
            t.a[i+1]++;
            t.a[i]-=MAXN+1;
        }
    }
    if(t.a[big]!=0)
        t.len=big+1;
    else t.len=big;
    return t;
}
BigNum BigNum::operator-(const BigNum &T)const //两个大数之间的相减运算
{
    int i,j,big;
    bool flag;
    BigNum t1,t2;
    if(*this>T) {
        t1=*this;
        t2=T;
        flag=0;
    } else {
        t1=T;
        t2=*this;
        flag=1;
    }
    big=t1.len;
    for(i=0; i<big; i++) {
        if(t1.a[i]<t2.a[i]) {
            j=i+1;
            while(t1.a[j]==0)
                j++;
            t1.a[j--]--;
            while(j>i)
                t1.a[j--]+=MAXN;
            t1.a[i]+=MAXN+1-t2.a[i];
        } else t1.a[i]-=t2.a[i];
    }
    t1.len=big;
    while(t1.a[len-1]==0 && t1.len>1) {
        t1.len--;
        big--;
    }
    if(flag)
        t1.a[big-1]=0-t1.a[big-1];
    return t1;
}
BigNum BigNum::operator*(const BigNum &T)const //两个大数之间的相乘
{
    BigNum ret;
    int i,j,up;
    int temp,temp1;
    for(i=0; i<len; i++) {
        up=0;
        for(j=0; j<T.len; j++) {
            temp=a[i]*T.a[j]+ret.a[i+j]+up;
            if(temp>MAXN) {
                temp1=temp-temp/(MAXN+1)*(MAXN+1);
                up=temp/(MAXN+1);
                ret.a[i+j]=temp1;
            } else {
                up=0;
                ret.a[i+j]=temp;
            }
        }
        if(up!=0)
            ret.a[i+j]=up;
    }
    ret.len=i+j;
    while(ret.a[ret.len-1]==0 && ret.len>1)ret.len--;
    return ret;
}
BigNum BigNum::operator/(const int &b)const //大数对一个整数进行相除运算
{
    BigNum ret;
    int i,down=0;
    for(i=len-1; i>=0; i--) {
        ret.a[i]=(a[i]+down*(MAXN+1))/b;
        down=a[i]+down*(MAXN+1)-ret.a[i]*b;
    }
    ret.len=len;
    while(ret.a[ret.len-1]==0 && ret.len>1)
        ret.len--;
    return ret;
}
int BigNum::operator%(const int &b)const //大数对一个 int类型的变量进行取模
{
    int i,d=0;
    for(i=len-1; i>=0; i--)
        d=((d*(MAXN+1))%b+a[i])%b;
    return d;
}
BigNum BigNum::operator^(const int &n)const //大数的n次方运算
{
    BigNum t,ret(1);
    int i;
    if(n<0)exit(-1);
    if(n==0)return 1;
    if(n==1)return *this;
    int m=n;
    while(m>1) {
        t=*this;
        for(i=1; (i<<1)<=m; i<<=1)
            t=t*t;
        m-=i;
        ret=ret*t;
        if(m==1)ret=ret*(*this);
    }
    return ret;
}
bool BigNum::operator>(const BigNum &T)const //大数和另一个大数的大小比较
{
    int ln;
    if(len>T.len)return true;
    else if(len==T.len) {
        ln=len-1;
        while(a[ln]==T.a[ln]&&ln>=0)
            ln--;
        if(ln>=0 && a[ln]>T.a[ln])
            return true;
        else
            return false;
    } else
        return false;
}
bool BigNum::operator>(const int &t)const //大数和一个int类型的变量的大小比较
{
    BigNum b(t);
    return *this>b;
}
void BigNum::print() //输出大数
{
    int i;
    printf("%d",a[len-1]);
    for(i=len-2; i>=0; i--)
        printf("%04d",a[i]);
    printf("\n");
}

// 以上kuangbin 大数模版
BigNum   get_sol(int d){
    double r=sqrt(d);
    unsigned long long a0=(unsigned long long)r;
    unsigned long long a=0;
    unsigned long long b=0,c=1;
    unsigned long long s=0;
    unsigned long long k[100];
    k[0]=a0;
    b=a0*c-b;
    c=(d-b*b)/c;
    a=(b+a0)/c;
    s++;
    k[s]=a;
    while(a!=2*a0){
        b=a*c-b;
        c=(d-b*b)/c;
        a=(b+a0)/c;
        s++;
        k[s]=a;
    }
    BigNum   p,q;
    for(int i=s-1;i>=0;i--)
    {
        if(i==s-1){
            p=1;
            q=k[i];
        }
        else{
            BigNum   tmp=q;
            q=BigNum  (k[i])*q+p;
            p=tmp;
        }
    }
    BigNum   x;
    if(s%2==0)
        x=q;
    else
        x=q*q*2+1;
    return x;
}
int main(){
    int n;
    cin>>n;
    BigNum   ans=0;
    BigNum   x;
    for(int d=2;d<=n;d++){
    if(((unsigned long long)sqrt(d+0.5))*((unsigned long long)sqrt(d+0.5))==d)
        continue;
        x=get_sol(d);
        if(x>ans){
            ans=x;
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

Fly

#include<bits/stdc++.h>
using namespace std;
int a[500010];
int dp[500010][15];
int maxn[15];
int main()
{
        memset(dp,0,sizeof(dp));
        memset(a,0,sizeof(a));
        memset(maxn,0,sizeof(maxn));
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n+1;i++)
        {
            for(int j=0;j<=k;j++) dp[i][j]=dp[i-1][j]+a[i];
            if(i>1)for(int j=0;j<=k;j++) dp[i][j]=max(dp[i][j],dp[i-2][j]+a[i]);
            for(int j=0;j<k;j++) dp[i][j+1]=max(dp[i][j+1],maxn[j]+a[i]);
            for(int j=0;j<k;j++) maxn[j]=max(maxn[j],dp[i][j]);
        }
    int ans=-2000000000;
    for(int i=0;i<=k;i++)ans=max(ans,dp[n+1][i]);
    printf("%d\n",ans);

    return 0;
}

 

字符串

#include<bits/stdc++.h>
using namespace std;
char s[110];
int dp[110][110];
bool judge(int a,int lena,int b,int lenb)
{
    while(lena&&lenb&&s[a+lena-1]==s[b+lenb-1]) lena--,lenb--;
    return lena==0;
}
string change(int x)
{
    if(x==0) return "0";
    string tmp="";
    while(x)
    {
        tmp=tmp+(char)(x%10+0);
        x/=10;
    }
    reverse(tmp.begin(),tmp.end());
    return tmp;
}
int cal(int x)
{
    int tot=0;
    while(x)
    {
        x/=10;
        tot++;
    }
    return tot;
}
map<int,string> mp;
string dfs(int l,int r)
{
    if(mp.find(l*1000+r)!=mp.end())
    {
        return mp[l*1000+r];
    }
    if(r-l+1<4)
    {
        string tmp="";
        for(int i=l;i<=r;i++) tmp=tmp+s[i];
        mp[l*1000+r]=tmp;
        return tmp;
    }
    if(dp[l][r]!=(r-l+1))
    {
        string tmp="";
        string tmp1=dfs(l,l+dp[l][r]-1);
        if(tmp1.size()+2+cal(dp[l][r])<(r-l+1))
        {
            tmp=tmp+change((r-l+1)/dp[l][r]);
            tmp=tmp+(;
            tmp=tmp+tmp1;
            tmp=tmp+);
        }
        else
        {
            for(int i=l;i<=r;i++) tmp=tmp+s[i];
        }
        mp[l*1000+r]=tmp;
        return tmp;
    }
    else{
        string ans="";
        int minans=r-l+2,minflag=r;
        for(int i=l;i<r;i++)
        {
            string tmp1=dfs(l,i);
            string tmp2=dfs(i+1,r);
            if(tmp1.size()+tmp2.size()<minans)
            {
                minans=tmp1.size()+tmp2.size();
                ans=tmp1+tmp2;
            }
        }
        mp[l*1000+r]=ans;
        return ans;
    }
}
int main()
{
   /* for(int cas=7;cas<8;cas++){
    char infile[]="data0.in";
    char outfile[]="data0.out";
    infile[4]=cas+‘0‘;
    outfile[4]=cas+‘0‘;
    freopen(infile,"r",stdin);
    freopen(outfile,"w",stdout);*/
    memset(s,0,sizeof(s));
    memset(dp,0,sizeof(dp));
    mp.clear();
    scanf("%s",s+1);
    for(int i=0;i<110;i++) dp[i][i]=1;
        int n=strlen(s+1);
        for(int len=2;len<=n;len++)
        {
            for(int l=1;l<=n;l++)
            {
                int r=l+len-1;
                if(r>n) break;
                dp[l][r]=r-l+1;
                for(int k=l;k<=r;k++)
                {
                    int la=k-l+1;
                    int lb=len-la;
                    if(la>lb) break;
                    if(lb%la) continue;
                    if(dp[k+1][r]==la)
                    {
                        if(judge(l,la,k+1,lb))
                        {
                            dp[l][r]=min(dp[l][r],dp[k+1][r]);
                        }
                    }
                }

            }
        }
        cout<<(int)dfs(1,n).size()<<endl;
    return 0;
}

 

异或和

规律自己打表可发现

#include<bits/stdc++.h>
using namespace std;

int main()
{
        int t;
        cin>>t;
        while(t--)
        {
            long long n;
            cin>>n;
            if(n%4==3){
                cout<<0<<endl;
            }
            else
            {
                if(n%4==0)
                    cout<<n<<endl;
                if(n%4==1)
                    cout<<(n^(n-1))<<endl;
                if(n%4==2)
                    cout<<(n^(n-1)^(n-2))<<endl;
            }
        }

    return 0;
}

 

正方形

智商题

#include<bits/stdc++.h>
using namespace std;
bool prime(long long  x){
   if(x==2) return 1;
   if(x%2==0) return 0;
   for(long long j=3;j*j<=x;j+=2){
       if(x%j==0) return 0;
   }
   return 1;
}
int main(){
   long long t;
   cin>>t;
   while(t--){
      long long  n,m;
      cin>>n>>m;
      if(n-m>1){
         cout<<"NO"<<endl;
      }else{
         if(prime(n+m)){
            cout<<"YES"<<endl;
         }else{
            cout<<"NO"<<endl;
         }
      }
   }
}

 

焦作选拔赛题解

标签:智商   bsp   重载   控制   题目   手写   fst   tar   cos   

原文地址:https://www.cnblogs.com/DyLoder/p/9769279.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!