浙大第十六届程序设计竞赛总结

zoj 3927 Programming Ability Test

题意:四个数的和大于等于80。这么招摇的广告,为了广告效应也得是道水题~~~

#include
#include
#include
#include
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--){
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
if(a+b+c+d>=80)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}

zoj 3929 Deque and Balls

搬砖的地址: http://blog.csdn.net/doris1104/article/details/51126910
题意:每次等概率地往一个序列的左边或右边放一个球,问期望的相邻逆序对有多少个。
思考出发点:当放入第 i 个球时,恰好在第 j 个球左边/右边的概率是多少?
稍微找一下规律就可以发现:i 号球
和 i – 1 号球相邻的概率是 ½
和 i – 2 号球相邻的概率是 ¼
以此类推,一个例外是与 1 号球相邻的概率和与 2 号球相邻的概率是相同的
做法思路:维护一个数据结构,用于查询比 x 小的元素的概率之和是多少,再维护一个数据结构,查询比 x 大的元素的概率之和是多少,然后把查询的结果加起来
既然如此,那就可以直接用一个数组,查询 x 时,计算不等于 x 的概率就行了
最后答案会乘以 2^n,因此所有的概率都能用整数表示,别算错就行了

#include<bits/stdc++.h>  
#define ll long long  
#define mod 1000000007  
using namespace std;  

ll power[100005];
ll r[100005];
ll dp[100005];
int main(){
    power[0]=1;
    for(int i=1;i<=100000;i++){
        power[i]=(power[i-1]*2)%mod;
    }
    int t,n,a;
    cin>>t;
    while(t--){
        memset(r,0,sizeof(r));  
        memset(dp,0,sizeof(dp));
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a;
            dp[i]=(dp[i-1]*2+power[i-2]-r[a]+mod)%mod;
            if(i==1)
                r[a]=(r[a]+1)%mod;
            else
                r[a]=(r[a]+power[i-2])%mod;
        }
        cout<<dp[n]*2%mod<<endl;
    }
    return 0;
}

zoj 3930 Dice Notation

题意:可以直接看样例的模拟题,但是要注意对换行符的处理。

#include<stdio.h>
#include<string.h>

char tmp[2000000+10],s[2000000+10];
char ans[2000000+10];
char u[2000000+10];
int  T,len,f;
int  g;

void init(){
    memset(tmp,0,sizeof(tmp));
    memset(ans,0,sizeof(ans));
    memset(s,0,sizeof(s));
    len=0;
    f=0;
}

void c(){
    for(int i=0;tmp[i];i++){
        if(tmp[i]=='d'||tmp[i]=='+'||tmp[i]=='-'||tmp[i]=='*'||tmp[i]=='/'||tmp[i]=='('
        ||tmp[i]==')'||(tmp[i]>='0'&&tmp[i]<='9'))
            s[len++]=tmp[i];
    }
}

void work(){
    int pre=0;
    int pos1,pos2;
    for(int i=0;s[i];i++){
        if(s[i]=='d'){
            pos1=i,pos2=i;
            for(int j=i+1;s[j];j++){
                if(s[j]>='0'&&s[j]<='9')
                    pos2=j;
                else 
                    break;
            }
            for(int j=i-1;j>=0;j--){
                if(s[j]>='0'&&s[j]<='9')
                    pos1=j;
                else
                    break;
            }
            int a=0;
            for(int j=pos1;j<=i-1;j++)
                a=a*10+s[j]-'0';
            for(int j=pre;j<pos1;j++)
                ans[f++]=s[j];
            pre=pos2+1;
            memset(u,0,sizeof(u));
            g=0;
            u[g++]='[';
            for(int j=i;j<=pos2;j++)
                u[g++]=s[j];
            u[g++]=']';
            if(a==0)
                a=1;
            if(a!=1)
                ans[f++]='(';
            for(int k=0;u[k];k++)
                ans[f++]=u[k];
            for(int j=1;j<=a-1;j++){
                ans[f++]='+';
                for(int k=0;u[k];k++)
                    ans[f++]=u[k];
            }
            if(a!=1)
                ans[f++]=')';
        }
    }
    for(int j=pre;s[j];j++)
        ans[f++]=s[j];
}

void print(){
    for(int i=0;ans[i];i++){
        if(ans[i]=='+'||ans[i]=='-'||ans[i]=='*'||ans[i]=='/')
            printf(" %c ",ans[i]);
        else
            printf("%c",ans[i]);
    }
    printf(" = [Result]\n");
}

int main(){
    scanf("%d",&T);
    getchar();
    while(T--){
        init();
        gets(tmp);
        c();
        work();
        print();
    }
    return 0;
}

zoj 3932 Handshakes

题意:贪心,当前拥有最多朋友的人总能和进来的人握手

#include <iostream>
#include <string> 
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
#include <algorithm>
#include <cmath>
using namespace std;
int a[100005],sum[100005];
int main()
{
  int t,n,maxx;
  scanf("%d",&t);
  while(t--)
  {
      maxx=0;
      scanf("%d",&n);
      for(int i=1;i<=n;i++)
      {
          scanf("%d",&a[i]);
      }
      a[n+1]=0;
      sum[n+1]=0;
      for(int i=n;i>=1;i--)
      {
          if(a[i+1])
          {
              sum[i]=sum[i+1]+1;
          }
          else
              sum[i]=sum[i+1];
          if(a[i]+sum[i]>maxx)
              maxx=a[i]+sum[i];
      }
      printf("%d\n",maxx);
  }
  return 0;
}

zoj 3933 Team Formation

题意:有 n 个人,每个人属于 0 组或是 1 组,现在想要组队,每个队伍必须是一个 0 组的人和一个 1 组的组队,问在组队数最多的情况下,队伍中的女生数量最多能有多少个?
解题思路:比较直白的带权匹配问题,权值要设大一点,可以用 KM 算法或是费用流解决,稍微有一些卡模板效率,最好还是用 KM。

#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std;
/* KM算法
 * 复杂度O(nx*nx*ny)
 * 求最大权匹配
 * 若求最小权匹配,可将权值取相反数,结果取相反数
 * 点的编号从0开始
 */
const int N = 505;
const int INF = 0x3f3f3f3f;
int nx,ny;//两边的点数 nx,第一队的个数,ny,第二队的个数。注意 nx <= ny,否则会死循环。
int g[N][N];//二分图描述  g[i][j],i属于第一队,j属于第二队。
int linker[N],lx[N],ly[N];//y中各点匹配状态,x,y中的点标号
int slack[N];
bool visx[N],visy[N];
bool DFS(int x)
{
    visx[x] = true;
    for(int y = 0; y < ny; y++)
    {
        if(visy[y])continue;
        int tmp = lx[x] + ly[y] - g[x][y];
        if(tmp == 0)
        {
            visy[y] = true;
            if(linker[y] == -1 || DFS(linker[y]))
            {
                linker[y] = x;
                return true;
            }
        }
        else if(slack[y] > tmp)
            slack[y] = tmp;
    }
    return false;
}
int KM()
{
    memset(linker,-1,sizeof(linker));
    memset(ly,0,sizeof(ly));
    for(int i = 0;i < nx;i++)
    {
        lx[i] = -INF;
        for(int j = 0;j < ny;j++)
            if(g[i][j] > lx[i])
                lx[i] = g[i][j];
    }
    for(int x = 0;x < nx;x++)
    {
        for(int i = 0;i < ny;i++)
            slack[i] = INF;
        while(true)
        {
            memset(visx,false,sizeof(visx));
            memset(visy,false,sizeof(visy));
            if(DFS(x))break;
            int d = INF;
            for(int i = 0;i < ny;i++)
                if(!visy[i] && d > slack[i])
                    d = slack[i];
            for(int i = 0;i < nx;i++)
                if(visx[i])
                    lx[i] -= d;
            for(int i = 0;i < ny;i++)
            {
                if(visy[i])ly[i] += d;
                else slack[i] -= d;
            }
        }
    }
    int res = 0;
    for(int i = 0;i < ny;i++)
        if(linker[i] != -1)
            res += g[linker[i]][i];
    return res;
}

int vis[505][505];
int main(){
    int t,n,a,m;
    cin>>t;
    while(t--){
        memset(linker,0,sizeof(linker));
        memset(g,0,sizeof(g));
        memset(vis,0,sizeof(vis));
        cin>>n;
        string Group,Sex;
        cin>>Group>>Sex;
        nx=ny=n;
        for(int i=0;i<n;i++){
            cin>>m;
            for (int j = 0; j < m; j++){
                cin >> a;
                vis[i][a - 1] = 1;
                vis[a - 1][i] = 1;
            }
            for(int j=0;j<n;j++){
                if(!vis[i][j]&&!vis[j][i]&&Group[i]!=Group[j]){
                    int ret=20000;
                    if(Sex[i]=='0') ret++;
                    if(Sex[j]=='0') ret++;
                    if(Group[i]=='0'&&Group[j]=='1') g[i][j]=ret;
                    else if (Group[i] == '1' && Group[j] == '0') g[j][i] = ret;
                }
            }
        }
        int res=KM();
        cout<<(res/20000)<<" "<<(res%10000)<<endl;
        for(int i=0;i<n;i++){
            if(linker[i]!=-1&&g[linker[i]][i]){
                cout << linker[i] + 1 << " " << i + 1 << endl;
            }
        }
    }
    return 0;
}

zoj 3935 2016

题意:既是三角形数又是六角形数且是闰年的数字

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<bitset>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<functional>
using namespace std;
typedef long long LL;
const int low(int x) { return x&-x; }
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 10;
int T, n, m;

int main() {
    for (int i = 2016, j = 476; i <= 990528; i += j)
    {
        if (i % 400 == 0 || i % 100 != 0) printf("%d\n", i);
        j += 64;
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容