第一次练习赛解题报告及标程

  因为实际的课程还没有开始讲,这次的练习赛着重于对上学期C++知识的复习,以及对数据结构课程内容的一些铺垫。主要考查了结构体、指针、预处理等相关知识。以下为简单的题解和标程。

  A. Page Turn

  签到题,改编自Pages, Codeforces Round #233 (Div. 2) A,太水了不多讲。看下标程可以写得多简洁就好。

//by trashLHC

#include<cstdio>
int main(){
    int n,p,k,start,end;
    while(~scanf("%d%d%d",&n,&p,&k)){
        start = 1+ (p-k-1)*((p-k)>0);
        end = n+(p+k-n)*(!(p+k>n));
        if(start!=1)  printf("<< ");
        for(int i=start;i<=end;i++)
            (i==p)?printf("(%d) ",i):printf("%d ",i);
        if(end!=n)  printf(">>");
        printf("\n");
    }
}
//by wjfwzzc

#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
    int n,p,k;
    while(~scanf("%d%d%d",&n,&p,&k))
    {
        if(p-k>1)
            printf("<< ");
        for(int i=max(1,p-k); i<=min(n,p+k); ++i)
            printf(i==p?"(%d) ":"%d ",i);
        if(p+k<n)
            printf(">>");
        putchar('\n');
    }
}

  B. SoRtiNg

  考查结构体的运用以及排序,数据量小,O(n^2)排序就可以过。这里分别给出两份标程。

  渣诚写的,用了直接选择排序,最常规的写法,不多说了。

//by trashLHC

#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
using namespace std;
typedef struct{
    string name;
    int ID;
    int AVscore;
    int GPA;
}Student;
int main(){
     int n;
     while(cin>>n){
          Student s[1001];
          for(int i=0;i<n;i++)
              cin>>s[i].name>>s[i].ID>>s[i].AVscore>>s[i].GPA;
          for(int i=0;i<n-1;i++)
              for(int j=0;j<n-i-1;j++){
                  if(s[j].AVscore<s[j+1].AVscore)
                      swap(s[j],s[j+1]);
                  else if(s[j].AVscore==s[j+1].AVscore){
                      if(s[j].GPA<s[j+1].GPA)
                          swap(s[j],s[j+1]);
                      else if(s[j].GPA==s[j+1].GPA)
                          if(s[j].ID>s[j+1].ID)
                             swap(s[j],s[j+1]);
                  }
              }
        for(int i=0;i<n;i++)
           cout<<s[i].name<<' '<<s[i].ID<<' '<<s[i].AVscore<<' '<<s[i].GPA<<endl;
     }
     return 0;
}

  我写的,sort排序,用到了运算符重载,C++2课上以后会讲到。具体的可以查阅sort函数用法。

//by wjfwzzc

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1005;
struct stu
{
    int score,gpa,num;
    char name[12];
    bool operator<(const stu &b) const
    {
        if(score==b.score)
        {
            if(gpa==b.gpa)
                return num<b.num;
            return gpa>b.gpa;
        }
        return score>b.score;
    }
} data[MAXN];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; ++i)
            scanf("%s%d%d%d",data[i].name,&data[i].num,&data[i].score,&data[i].gpa);
        sort(data,data+n);
        for(int i=0; i<n; ++i)
            printf("%s %d %d %d\n",data[i].name,data[i].num,data[i].score,data[i].gpa);
    }
}

  C. A+B again

  大数相加,很古董的题了……考查数组的理解,以及一定的编码能力;注意一下进位和0即可。

//by trashLHC

#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);getchar();
    char a[1111],b[1111],c[1111];
    while(t--)
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        scanf("%s%s",a,b);
        int i,l1=strlen(a),l2=strlen(b);
        for(i=0;i<l1/2;i++)
           swap(a[i],a[l1-i-1]);
        for(i=0;i<l2/2;i++)
           swap(b[i],b[l2-i-1]);
        for(i=0;i<max(l1,l2);i++)
        {
            if(a[i]>='0'&&a[i]<='9')  c[i]+=a[i]-'0';
            if(b[i]>='0'&&b[i]<='9')  c[i]+=b[i]-'0';
            c[i+1]+=c[i]/10;
            c[i]%=10;
        }
        if(c[i]==0)i--;
        for(;i>=0;i--)
           printf("%c",c[i]+'0');
        printf("\n");
    }
}

  这里放出一个用栈实现的版本,使用了STL。实际大数相加没有这么写的,仅供娱乐。网上相关的代码很多,漂亮的大数模板也很多,可以自行查找学习。

//by wjfwzzc

#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
const int MAXN=100005;
char sta[MAXN],stb[MAXN];
stack<char> sa,sb,ans;
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s%s",sta,stb);
        int la=strlen(sta),lb=strlen(stb);
        for(int i=0; i<la; ++i)
            sa.push(sta[i]);
        for(int i=0; i<lb; ++i)
            sb.push(stb[i]);
        int tmp=0;
        while(!sa.empty()||!sb.empty())
        {
            char ta='0',tb='0';
            if(!sa.empty())
            {
                ta=sa.top();
                sa.pop();
            }
            if(!sb.empty())
            {
                tb=sb.top();
                sb.pop();
            }
            tmp+=ta-'0'+tb-'0';
            ans.push(char(tmp%10+'0'));
            tmp/=10;
        }
        if(tmp>0)
            ans.push(char(tmp+'0'));
        while(!ans.empty())
        {
            putchar(ans.top());
            ans.pop();
        }
        putchar('\n');
    }
}

  再放一个从我的高精度模板节选的一部分。

//by wjfwzzc

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int ten[4]= {1,10,100,1000};
const int maxl=100005;
struct BigNumber
{
    int d[maxl];
    BigNumber(string s)
    {
        int len=s.size();
        d[0]=(len-1)/4+1;
        for(int i=1; i<maxl; ++i)
            d[i]=0;
        for(int i=len-1; i>=0; --i)
        {
            int j=(len-i-1)/4+1,k=(len-i-1)%4;
            d[j]+=ten[k]*(s[i]-'0');
        }
        while(d[0]>1&&d[d[0]]==0)
            --d[0];
    }
    BigNumber()
    {
        *this=BigNumber(string("0"));
    }
    string toString()
    {
        string s("");
        int i,j,tmp=d[d[0]];
        for(i=3; i>=1; --i)
            if(d[d[0]]>=ten[i])
                break;
        for(j=i; j>=0; --j)
        {
            s=s+char(tmp/ten[j]+'0');
            tmp%=ten[j];
        }
        for(i=d[0]-1; i>0; --i)
        {
            tmp=d[i];
            for(j=3; j>=0; --j)
            {
                s=s+char(tmp/ten[j]+'0');
                tmp%=ten[j];
            }
        }
        return s;
    }
} ;
BigNumber operator+(const BigNumber &a,const BigNumber &b)
{
    BigNumber c;
    c.d[0]=max(a.d[0],b.d[0]);
    int x=0;
    for(int i=1; i<=c.d[0]; ++i)
    {
        x+=a.d[i]+b.d[i];
        c.d[i]=x%10000;
        x/=10000;
    }
    while(x!=0)
    {
        c.d[++c.d[0]]=x%10000;
        x/=10000;
    }
    return c;
}
int main()
{
    int n;
    string sta,stb;
    cin>>n;
    while(n--)
    {
        cin>>sta>>stb;
        BigNumber a(sta),b(stb);
        cout<<(a+b).toString()<<endl;
    }
}

  D. Chem Is A Fourth Try

  陈题。矩阵中行或列的交换,希望考查到指针的应用,很可耻地失败了……因为完全可以用一个类似于hash表的方式模拟指针。这里放出两份代码。

  渣诚写的,用了指针,写得繁琐了一点,那时渣诚和我都太年轻。

//by trashLHC

#include<iostream>
#include<cstdio>
#include<fstream>
using namespace std;
int n,m,k,*p1[1001],*p2[1001],a,b,*tmp,colS[10001][2],rowS[10001][2],numC,numR;
char c;
int main()
{
    while(scanf("%d%d%d",&n,&m,&k)!=EOF)
    {
        numC=numR=0;
        for(int i=0;i<n;i++)
           p1[i]=new int[m];
        for(int i=0;i<m;i++)
           p2[i]=new int[n];
        for(int i=0;i<n;i++)
           for(int j=0;j<m;j++)
              scanf("%d",&p1[i][j]);
        for(int i=0;i<k;i++)
        {
            scanf(" %c %d%d",&c,&a,&b);
            if(c=='R')   {rowS[numR][0]=a-1;rowS[numR++][1]=b-1;} 
            else         {colS[numC][0]=a-1;colS[numC++][1]=b-1;} 
        }
        for(int i=0;i<numR;i++)
        {
            tmp=p1[rowS[i][0]];
            p1[rowS[i][0]]=p1[rowS[i][1]];
            p1[rowS[i][1]]=tmp;
        }
        for(int i=0;i<n;i++)
           for(int j=0;j<m;j++)
             p2[j][i]=p1[i][j];
        for(int i=0;i<numC;i++)
        {
            tmp=p2[colS[i][0]];
            p2[colS[i][0]]=p2[colS[i][1]];
            p2[colS[i][1]]=tmp;
        }
        for(int i=0;i<n;i++)
        {
           for(int j=0;j<m;j++)
              printf("%d ",p2[j][i]);
           printf("\n");
        }
        for(int i=0;i<n;i++)
           delete[] p1[i];
        for(int i=0;i<m;i++)
           delete[] p2[i];                      
    }
}

  我写的,没用指针,下标为0的行和列起到hash的作用。

//by wjfwzzc

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1005;
int g[MAXN][MAXN];
int main()
{
    int n,m,k,p,q;
    char c;
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        for(int i=1; i<=n; ++i)
            g[i][0]=i;
        for(int i=1; i<=m; ++i)
            g[0][i]=i;
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=m; ++j)
                scanf("%d",&g[i][j]);
        while(k--)
        {
            scanf(" %c%d%d",&c,&p,&q);
            switch(c)
            {
            case 'R':
                swap(g[p][0],g[q][0]);
                break;
            case 'C':
                swap(g[0][p],g[0][q]);
                break;
            }
        }
        for(int i=1; i<=n; ++i)
        {
            for(int j=1; j<=m; ++j)
                printf("%d ",g[g[i][0]][g[0][j]]);
            putchar('\n');
        }
    }
}

  E. SubMatrix++
  F. SubMatrix+++++

  分别是查询子矩阵的和,以及查询子矩阵不同数字的个数。因为当时OJ对测试数据的限定过小,导致这两道题被很多人用O(n)甚至O(n^2)的查询水过去了,没有达到考查预处理的目的。于是第二次练习赛重出了这两道题,并加大了数据量。题解和标程下次放出。

  G. Counting Pairs

  改编自Magic Pairs, CodeChef December Challenge 2013。这道题应该比较水,但是过题数不尽人意。要注意题目安排是随机的,并不是按照难度排序。所有配对减去身价相同的配对就是答案。注意第二轮数据10^5的数据量,需要用O(nlogn)的排序,且配对数达到10^10级别,需要用long long,这是一个小trick。

//by wjfwzzc

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=100005;
int a[MAXN];
int main()
{
    long long n;
    while(~scanf("%lld",&n))
    {
        for(int i=0; i<n; ++i)
            scanf("%d",&a[i]);
        sort(a,a+n);
        long long equal=0;
        for(int i=1; i<n; ++i)
        {
            long long cnt=1;
            while(a[i]==a[i-1])
            {
                ++i;
                ++cnt;
            }
            equal+=cnt*(cnt-1)/2;
        }
        printf("%lld\n",n*(n-1)/2-equal);
    }
}

  以上是wjfwzzc写的渣题解,有不明白的欢迎小窗或邮件。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值