第九届浙江财经大学信息学院大学生程序设计竞赛

A:水水更健康

时间限制: 1 Sec   内存限制: 128 MB
[ 提交][ 状态][ 讨论版]

题目描述

zhourist是zufeoj的Rank2。他决定向Rank1发起进攻号角。于是他要刷爆oj,但是他平时忙于结交学妹,没有很多时间来做这些题,于是他想尽可能的做简单题来节省时间。所以他决定只做难度系数低于n的题。 下面给你n和m 接下来m行是每道题的难度求出zhourist做的题数 sum。

输入

接下来m行是每道题的难度求出zhourist做的题数 sum。n,m(n,m<20)(n如题意,m为zhourist未刷的题数)接下来m行每行一个数字表示该题难度系数

输出

sum

样例输入

3 3
1
3
5

样例输出

1
题解:签到题.只要删选一下难度低于n的有多少题数
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
 
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        int x;
        int ans=0;
        for(int i=0;i<m;i++){
            scanf("%d",&x);
            if(x<n)
                ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}



  
   

B: 秘密改动

时间限制: 1 Sec   内存限制: 128 M [ 提交][ 状态][ 讨论版]

题目描述

zhourist的威名在学弟学妹中口口相传,他的仰慕者更是数都数不清。为了避免来自学妹的情书被发现,zhourist的电脑收到的信息都将进行改动增加偷看者的阅读难度,他想实现让收到的信息的奇数为变为小写字母,偶数位变为大写字母,其他信息不做改动,请帮他实现。

输入

字符串(长度<10000)

输出

结果

样例输入

12Aaaaa

样例输出

12aAaAa
题解:一个简单的模拟题,如果在奇数位,他是字母,那么把这个字母便为小写字母,在
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
char s[10100];
 
int main(){
    while(scanf("%s",s)!=EOF){
        int len=strlen(s);
        for(int i=0;i<len;i++){
            if(i%2==0){//变为小写
                if(s[i]>='A'&&s[i]<='Z')
                    s[i]=char(s[i]+32);
            }
            else{
                if(s[i]>='a'&&s[i]<='z')
                    s[i]=char(s[i]-32);
            }
        }
        printf("%s\n",s);
    }
    return 0;
}


  
   

C: boom

时间限制: 1 Sec   内存限制: 128 MB [ 提交][ 状态][ 讨论版]

题目描述

爆破组有n包炸药,每包炸药有一定的药量,现在需要爆破A,B两个地点,A地点可以放置两包炸药,B地点只能放置一包炸药,爆破的效果为两地点药量的乘积,请给出最好效果。

输入

n(3<=n<=1000) n个数(<200000)

输出

效果值

样例输入

3
1 2 3

样例输出

9
题解:分析可知,选择放在A,B的炸药一定是药量最多的三包,设为a,b,c(a<=b<=c),
一定是a,b放在A点,c放在B点,因为(a+b)*c>=(b+c)*a,(a+b)*c>(a+c)*b
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int a[1010];
 
bool cmp(int x,int y){
    return x>y;
}
 
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        sort(a+1,a+n+1,cmp);
        printf("%lld\n",(long long)a[1]*(a[2]+a[3]));
    }
    return 0;
}

D: 会长爱数学

时间限制: 1 Sec   内存限制: 128 MB
[ 提交][ 状态][ 讨论版]

题目描述

会长不仅是个爱晨刷的girl,也特别喜欢数学呢。然而她已经不满足于高数线代这些简单玩意了,
她要自己定义一种运算改变世界!有一天她垂死梦中惊坐起,突然就想到了一种新的运算F(X)。
如F(123)=1*2+2*3+3*1=11。她发现对于所有的数字来说不停的运用 F 函数会进入一个循环,例如
F(123)=11,F(11)=2, F(2)=4 ,F(4)=16, F(16)=12 ,F(12)=4,循环节的大小就是3。

现在,我们定义 X 的循环节大小为 G(X) 。
现在会长要用自己的方法考验你,给你一个 X ,请你计算G(X)。

如果不知道循环节是什么,请看两个例子:

如果输入了4,你应该输出3
F(4)=16, F(16)=12 ,F(12)=4,F(4)=16... ...
F(4)=16, F(16)=12 ,F(12)=4 为循环节,所以循环节长度为3,即G(4)=3。

如果输入了123,你应该输出3
F(123)=11,F(11)=2, F(2)=4 ,F(4)=16, F(16)=12 ,F(12)=4,F(4)=16... ...
F(4)=16, F(16)=12 ,F(12)=4 为循环节,所以循环节长度为3,即G(123)=3。

输入

多组测试数据,每组测试数据输入一个整数x(x<=1000000)

输出

对于每组测试数据,输出一个整数,代表 G(x)。 

样例输入

1
4

样例输出

1
3
暴力,把每个出现的数标记为他出现的位置,如果一个数第二次出现,那么便可以求出他的循环节为第二次出现的位置减去第一次出现的位置
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
map<int,int>mp;
int a[100];

int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        mp.clear();
        for(int i=1;i;i++){
            int cnt=0;
            int m=0;
            while(n>0){
                a[cnt++]=n%10;
                n/=10;
            }
            a[cnt]=a[0];
            for(int j=0;j<cnt;j++)
                m+=a[j]*a[j+1];
            n=m;
            if(mp[m]!=0){
                printf("%d\n",i-mp[m]);
                break;
            }
            else
                mp[m]=i;
        }
    }
    return 0;
}

E: 伟大先知的教导

时间限制: 1 Sec   内存限制: 128 MB
[ 提交][ 状态][ 讨论版]

题目描述

编写一个c/c++程序的过程大致如下:
1.  在文本编辑器中编辑(edit)代码,得到.c/.cpp的源文件
2.  将上步得到的文件通过编译器编译(compile)获得源代码,之后与所需的库代码链接(link)起来得到.exe的可执行文件
3.  运行(run)上步得到的可执行文件,查看运行结果
4.  如果运行过程中出现错误或未知中断,可能需要用调试器进行调试(debug),直到获得正确结果
 
那么现在我们来考虑在Windows或者Linunx环境下的情况,每一步我们可以选用不同的软件来完成任务。比较知名的文本编辑器有Vim(编辑器之神)、Emacs(神之编辑器)、sublime text 2/3(史上最优雅的编辑器)、Geany(我编不下去)等等,编译器和调试器可以选用MinGW中集成的gcc、g++和gdb。当然,也可以采用集成开发环境(IDE,Integrated Development Environment)进行编程,比如Code::Blocks、Visual Studio 2013/2015、Dev-Cpp等等。

看完上面资料之后,我们可以发现在ACM这种分秒必争的激烈比赛中,采用IDE是一种高速且有效的编程方式。所以,伟大的先知(也是编程鬼才)Zhourist曾经教导过我们“等他们配置好Vim,我早就用Code::Blocks抢到一血了!!!”
 
不幸地是,某些比赛中主办方可能不会提供IDE(众所周知大部分IDE属于商业软件)。我们也可以采用Vim(因为Vim是Linux中的标配)和MinGW来编写程序。讲了那么多,我们又发现在一个新的环境中,快速寻找到合适的编程软件是多么重要。接下来的问题是如何查看一台电脑的桌面中有没有Code::Blocks或Vim。并按Output中的描述输出结果。

输入

每组测试数据第一行为一个数字m,m代表桌面中图标的行数(m<=10),测试数据不超过1000组。

 
接下来每一行为一串字符,代表桌面对应行图标,长度小于1000 长度小于 50 ,相邻单词间用 # 隔开

每一组测试数据代表一台电脑的桌面,你的任务是寻找这个桌面中有没有Code::Blocks或Vim(严格区分大小写,符号为半角符号),并按要求输出结果。
友情提示:字符串的读入请使用scanf或者cin,其余的方式可能导致答案错误、输出超限等错误。

输出

对于每组数据,按下面描述输出结果(输出结果均为西文字符,具体参考样例输出)。
如果可以找到Code::Blocks和Vim,请输出“I can find Code::Blocks and Vim! ! !”(不包含引号,下同)。
如果只能找到Code::Blocks,请输出“I can find Code::Blocks! !”。
如果只能找到Vim,请输出“I can find Vim!”。
否则,请输出“Are you kidding me?”
输出中没有多余空行。

样例输入

1
Code::Blocks#Vim
2
Code::Blocks
vim#QQ
1
Vim
1
QQ#hearthstone

样例输出

I can find Code::Blocks and Vim! ! !
I can find Code::Blocks! !
I can find Vim!
Are you kidding me?

题解:水题,按照题目所给的意思做便可以了
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
char s[1010];
char s1[1100];
char *a="Code::Blocks";
char *b="Vim";
 
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        int flag1=0,flag2=0;
        for(int j=0;j<n;j++){
            scanf("%s",s);
            int len=strlen(s);
            int cnt=0;
            for(int i=0;i<len;i++){
                if(s[i]!='#'){
                    s1[cnt++]=s[i];
                }
                else{
                    s1[cnt]='\0';
                    if(strcmp(s1,a)==0)
                        flag1=1;
                    if(strcmp(s1,b)==0)
                        flag2=1;
                    cnt=0;
                }
            }
            if(s[len-1]!='#'){
                s1[cnt]='\0';
                if(strcmp(s1,a)==0)
                    flag1=1;
                if(strcmp(s1,b)==0)
                    flag2=1;
                cnt=0;
            }
        }
        if(flag1==1&&flag2==1)
            printf("I can find Code::Blocks and Vim! ! !\n");
        else  if(flag1==0&&flag2==1)
            printf("I can find Vim!\n");
        else  if(flag1==1&&flag2==0)
            printf("I can find Code::Blocks! !\n");
        else
            printf("Are you kidding me?\n");
    }
    return 0;
}
<center style="color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; line-height: 18px;"><h2 style="margin: 0px; font-family: inherit; color: blue; text-rendering: optimizeLegibility; font-size: 24px; line-height: 36px;">1010: 石锅全拌</h2><span class="green" style="color: green;">时间限制: </span>1 Sec  <span class="green" style="color: green;">内存限制: </span>128 MB
[<a target=_blank href="http://oj.haihongblog.com/submitpage.php?id=1010" style="color: rgb(26, 92, 200); text-decoration: none;">提交</a>][<a target=_blank href="http://oj.haihongblog.com/problemstatus.php?id=1010" style="color: rgb(26, 92, 200); text-decoration: none;">状态</a>][<a target=_blank href="http://oj.haihongblog.com/bbs.php?pid=1010" style="color: rgb(26, 92, 200); text-decoration: none;">讨论版</a>]</center><h2 style="margin: 0px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: blue; text-rendering: optimizeLegibility; font-size: 24px; line-height: 36px;">题目描述</h2><div class="content" style="font-family: 'Times New Roman'; font-size: 20px; line-height: 24px; height: auto; margin: 0px; padding: 0px 20px; color: rgb(51, 51, 51); background: none 0px 0px repeat scroll rgb(228, 240, 248);"><p style="margin-top: 0px; margin-bottom: 9px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; line-height: 18px;"><span style="font-size:14px;">石锅全拌来到了一家神奇的餐厅,这家餐厅的菜单中有各种各样的好吃的,但是这家餐厅的规矩是只能点菜单上连续的一段菜。石锅全拌心里自然是想菜单上有的全部点一份,可是摸摸口袋发现钱没带够。由于计算总价太过麻烦,请你写一段程序,每当石锅全拌选择好要点的起点和终点时立刻告诉他这么点菜需要花多少钱。</span></p></div><h2 style="margin: 0px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: blue; text-rendering: optimizeLegibility; font-size: 24px; line-height: 36px;">输入</h2><div class="content" style="font-family: 'Times New Roman'; font-size: 20px; line-height: 24px; height: auto; margin: 0px; padding: 0px 20px; color: rgb(51, 51, 51); background: none 0px 0px repeat scroll rgb(228, 240, 248);"><p style="margin-top: 0px; margin-bottom: 9px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; line-height: 18px;"><span style="font-size:14px;">输入包含多组测试数据,每组测试数据第一行输入两个整数 </span><span style="font-size:14px;">n,m(n是菜单上的菜品数<100000,m是石锅全拌选择的次数<10000)
接下来一行有n个整数,a1 a2 ... an,表示各菜的价格(ai<10000)
接下来m行,每行输入两个数,表示他选择的起点和终点</span></p></div><h2 style="margin: 0px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: blue; text-rendering: optimizeLegibility; font-size: 24px; line-height: 36px;">输出</h2><div class="content" style="font-family: 'Times New Roman'; font-size: 20px; line-height: 24px; height: auto; margin: 0px; padding: 0px 20px; color: rgb(51, 51, 51); background: none 0px 0px repeat scroll rgb(228, 240, 248);"><p style="margin-top: 0px; margin-bottom: 9px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; line-height: 18px;"><span style="font-size:14px;">对于每组测试数据,输出m行,每一行代表他选择的起点和终点之间的价值之和。</span></p></div><h2 style="margin: 0px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: blue; text-rendering: optimizeLegibility; font-size: 24px; line-height: 36px;">样例输入</h2><pre class="content" style="padding: 8.5px; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12.025px; color: rgb(51, 51, 51); border-radius: 4px; margin-top: 0px; margin-bottom: 9px; line-height: 18px; border: 1px solid rgba(0, 0, 0, 0.14902); white-space: pre-wrap; word-break: break-all; word-wrap: break-word; background-color: rgb(245, 245, 245);"><span class="sampledata" style="font-family: monospace; font-size: 18px; white-space: pre; background: none 0px 0px repeat scroll rgb(141, 184, 255);">3 1
1 2 3
1 3</span>

样例输出

6

样例输出

6

 
 
 题解:水题,利用前缀和便可以很快解决 
 
 
 
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int sum[101000];
 
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        sum[0]=0;
        int x;
        for(int i=1;i<=n;i++){
            scanf("%d",&x);
            sum[i]=sum[i-1]+x;
        }
        int l,r;
        while(m--){
            scanf("%d%d",&l,&r);
            printf("%d\n",sum[r]-sum[l-1]);
        }
    }
    return 0;
}

F: 贪心的小猫咪

时间限制: 1 Sec   内存限制: 128 MB
[ 提交][ 状态][ 讨论版]

题目描述

“老鼠你们都给我听着!”
对于老鼠来说,一只可爱的小猫咪恍若一个邪恶的撒旦。
“最近我可是越来越无聊了,所以我打算找几只老鼠陪我玩耍,不过呢,我现在给你们一个数,你们可以删去一位,然后剩下的数字就是要陪我玩的数量!”
不过可爱的小猫咪数学不是很好,所以对于他来说只有1-9的数字,所以他给你的数字不会出现0.
于是老鼠们一起去找老鼠长老商讨,希望能得到最少的数量。

输入

输入包含多组测试数据,每组测试数据输入一个非负整数 (数字的位数小于1000000位)

输出

对于每组测试数据,请输出删除一位之后,形成的最小的数。

样例输入

121

样例输出

11
题解:如果刚开始是递增的(注意没有说严格单调递增),则删除递增序列的最后一个数,如果递减,则删去第一个
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
char s[1000100];
 
int main(){
    while(scanf("%s",s)!=EOF){
        int len=strlen(s);
        int flag=0;//0表示数值一直重复
        int x=-1;
        for(int i=1;i<len;i++){
            if(s[i]>s[i-1]){    //找出一个上升序列
                if(flag!=1){
                    flag=-1;    //表示单调递增
                    x=i;
                }
                else if(flag==1){   //flag=1表示单调递减,如果出现递增,则删去单调递减的第一位
                    break;
                }
            }
            else if(s[i]<s[i-1]){
                if(flag==0){
                    flag=1;    //表示单调递减
                    x=i-1;
                }
                else if(flag==-1)  //如果出现递减,则删去单调递增序列的最后一位
                    break;
            }
        }
        if(x==-1)
            x=0;
        for(int i=0;i<len;i++){
            if(i!=x)
                printf("%c",s[i]);
        }
        printf("\n");
    }
    return 0;
}

G: 会长晨刷记

时间限制: 1 Sec   内存限制: 128 MB
[ 提交][ 状态][ 讨论版]

题目描述

晨刷是个好活动!ACM会长路明非特别热衷于晨刷,尤其是路程变长时间变短了之后。
可是最近天天下雨,晨刷的路上有各种水坑,踩到水坑就会弄湿美美的鞋子和裤子,
因此会长很烦恼:还让不让人愉快的晨刷了?!
于是会长想知道自己该如何巧妙避开各种水坑。
假设从起点到终点有n米,其中有m个水坑是需要避开的,会长每次可以走1米2米3米或者4米。
请问在这种情况下,会长有多少种方式避开水坑到达终点。

输入

输入包含多组输入,每组测试数据第一行两个整数n,m(n,m<=1000),第二行m个整数,a[1],a[2],a[3],a[4].....a[m],表示水坑的位置(即在 a[i] (1<=i<=m) 米处有水坑)

输出

输出避开水坑到达终点的方法数。由于答案会很大,输出答案对 20152016 取模

样例输入

4 2
1 3

样例输出

2

题解:一个简单的dp,dp[n]=dp[n-1]+dp[n-2]+dp[n-3]+dp[n-4]
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
long long dp[1100];
int flag[1100];
const int MOD=20152016;
 
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        memset(flag,0,sizeof(flag));
        int x;
        for(int i=1;i<=m;i++){
            scanf("%d",&x);
            flag[x]=1;
        }
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        for(int i=1;i<=n;i++){
            if(flag[i]==1)
                continue;
            if(i==1)
                dp[1]=dp[i-1];
            else if(i==2)
                dp[i]=dp[i-1]+dp[i-2];
            else if(i==3)
                dp[i]=dp[i-1]+dp[i-2]+dp[i-3];
            else
                dp[i]=(dp[i-4]+dp[i-3]+dp[i-2]+dp[i-1])%MOD;
        }
        printf("%lld\n",dp[n]);
    }
    return 0;
}

I: 周末出游

时间限制: 1 Sec   内存限制: 128 MB
[ 提交][ 状态][ 讨论版]

题目描述

周末天气真好,大家组织一起出去玩(玩你妹,不好好学习),可是,有些人要知道(有好朋友了不起呀)自己最要好的朋友接受邀请了,他才会去,只有邀请到他们最好的朋友才会去(贱人就是矫情)。可是作为负责人的你(冤大头)必须判断是否能够办好这次聚会(气死爸爸拉,哼),邀请到所有的人

输入

输入包含多组测试数据,每组测试数据第一行输入n(0<n<1000),表示有n个人。然后第二行输入n个数,a[1],a[2],a[3].....a[n] (0<a[i]<=n) 。

对于第 i 个人来说,a[i] 是他的好朋友, 如果 a[i] 参加了,那么 i 也会参加。

如果a[i]=i,表示编号为 i 的同学一定会去(注孤)。

输出

如果能邀请到所有输出yes,反之no。

样例输入

4
1 2 3 3

样例输出

yes
题解:拓扑排序
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
vector<int>G[1100];
int degree[1100];
int tot,head[1100];
 
void init(){
    tot=0;
    memset(head,-1,sizeof(head));
}
 
struct Edge{
    int to,next;
}e[2200];
 
void addedge(int u,int v){
    e[tot].to=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
 
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        memset(degree,0,sizeof(degree));
        init();
        int x;
        for(int i=1;i<=n;i++){
            scanf("%d",&x);
            if(x==i)
                degree[i]=0;
            else{
                degree[i]=1;
                addedge(x,i);
            }
        }
        queue<int>Q;
        int cnt=0;
        for(int i=1;i<=n;i++){
            if(degree[i]==0)
                Q.push(i);
        }
        while(!Q.empty()){
            int u=Q.front();
            Q.pop();
            cnt++;
            for(int i=head[u];i!=-1;i=e[i].next)
                Q.push(e[i].to);
        }
        if(cnt==n)
            printf("yes\n");
        else
            printf("no\n");
    }
    return 0;
}

J: 贪吃的松鼠

时间限制: 1 Sec   内存限制: 2 MB
[ 提交][ 状态][ 讨论版]

题目描述

冬天到了,n只松鼠决定一起采集一波坚果过冬,可是在松树老大清点的时候,发现少了一些食物,于是召开松鼠大会,知道是有一只小松鼠偷吃了一部分食物!可是他们只知道每一个松鼠运了m个,但是某一个只松鼠运了k个,请找出这个松鼠(注意:本题提供内存仅为2MB)

输入

输入有多组数据,每组第一行包含三个数n,m,k(n<=100000,1<m<=9,k<m)。
然后输入m*(n-1)+k个数,第i个数表示运送第i个坚果的松鼠编号,编号范围在2^30以内

输出

输出松鼠编号

样例输入

3 3 2
1 2 1 2 1 2 3 3

样例输出

3
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int maxn=1<<15;
const int M=(1<<15)-1;
int a[maxn],b[maxn];
 
int main(){
    int n,m,k;
    while(scanf("%d%d%d",&n,&m,&k)!=EOF){
        int x;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(int i=1;i<=(n-1)*m+k;i++){
            scanf("%d",&x);
            //将x分成两个部分,假设有30位,1-15位一组,16-30位为一组
            a[(x>>15)]++;
            b[(x&M)]++;
        }
        int ans=0;
        for(int i=0;i<M;i++){
            if(a[i]%m!=0)   //只有一组不成立
                ans=ans|(i<<15);
            if(b[i]%m!=0)   //只有一组不成立
                ans=ans|i;  //所以两组异或的和便为答案
        }
        printf("%d\n",ans);
    }
    return 0;
}

K: God Wang

时间限制: 1 Sec   内存限制: 128 MB
[ 提交][ 状态][ 讨论版]

题目描述

巴拉巴拉巴拉。O(∩_∩)O。老司机最近想提升自己的魅力,于是他准备吃一些“魅力糖果”。老司机魅力的初始值为K。想吃一个魅力糖果当然有限制条件啦,只有当司机的魅力值大于等于这个魅力糖果的魔力值(每个魅力糖果都有一个魔力值)、并且之前没有吃过这一颗糖果的时候,老司机才能吃这一颗糖果,吃完之后,这颗糖果下一次就不能被吃了,并且司机的魅力值增加了1单位。

一天,项神降临于人间,在地上画了一个很大的圆圈,想诅咒老司机。不料,魅力仙女是爱司机的,她希望司机的魅力值得到提升,仙女在大圆圈上摆上了N个魅力糖果,并且给这些糖果编上了序号,1,2,3,4,5......,N,并且给出了每一个糖果的魔力值a[1],a[2],a[3]....a[N].

现在,老司机站在编号为1的糖果上,他依次走向编号为2,3,4,5,....N,1,2,3,4,5,...N,1,2,3,4的糖果(因为是一个圆圈,所以走过编号为N的糖果之后,会走到编号为1的糖果,一直循环),走的过程中,如果司机当前的魅力值大于等于目前所在地糖果的魔力值并且这颗糖果之前没有被吃过,那么司机就必须吃下这颗糖果,司机的魔力值就会加1.

那么问题来了,如果老司机的魔力值最终可以为N+K,那么请输出他吃糖果的编号的顺序,否则输出-1.

输入

多组测试数据,每组测试数据,第一行N,K,N表示有N个糖果,K表示老司机魔力的初始值,第二行N个数字,第i个数字表示编号为i的糖果的魔力值为a[i]。所有输入数据范围大于0,小于等于100000

输出

如果老司机的魅力值最终能达到N+K请输出吃的糖果的编号的顺序,否则输出-1。

样例输入

5 0
0 1 2 3 4

样例输出

1 2 3 4 5
题解:线段树查询区间最小值
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include<map>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include<set>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf -0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
const int maxn=100000;
int minv[maxn*4+1000];
int a[maxn+100];
int L,R,p;
int n,k;
void pushup(int rt){
    minv[rt]=min(minv[rt<<1],minv[rt<<1|1]);
}
 
void build(int l,int r,int rt){
    if(l==r){
        minv[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
 
void update(int l,int r,int rt){
    if(l==r){
        minv[rt]=INF;
        return ;
    }
    int m=(l+r)>>1;
    if(p<=m)
        update(lson);
    else
        update(rson);
    pushup(rt);
}
 
int ans[maxn],ans_num;
 
void query(int l,int r,int rt){
    if(l==r){
        ans_num=l;
        return ;
    }
    int m=(l+r)>>1;
    if(L<=m&&minv[rt<<1]<=k&&minv[rt<<1]!=-1)
        query(lson);
    if(ans_num!=0)
        return ;
    if(R>m&&minv[rt<<1|1]<=k&&minv[rt<<1|1]!=-1)
        query(rson);
}
 
int main(){
    while(scanf("%d%d",&n,&k)!=EOF){
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        build(1,n,1);
        L=1,R=n;
        int flag=1;
        for(int i=1;i<=n;i++){
            ans_num=0;
            if(L<=R)    //查询右半部分
                query(1,n,1);
            if(ans_num!=0){
                L=ans_num+1;
                ans[i]=ans_num;
                k++;
                p=ans_num;
                update(1,n,1);
            }
            else{
                ans_num=0;  //查询左半部分
                R=L-1,L=1;
                if(L<=R)
                    query(1,n,1);
                if(ans_num!=0){
                    ans[i]=ans_num;
                    L=ans_num+1;
                    k++;
                    p=ans_num;
                    update(1,n,1);
                }
                R=n;
            }
            if(ans_num==0){
                flag=0;
                break;
            }
        }
        if(flag==0)
            printf("-1\n");
        else{
            printf("%d",ans[1]);
            for(int i=2;i<=n;i++)
                printf(" %d",ans[i]);
            printf("\n");
        }
    }
    return 0;
}

L: GW I (3)

时间限制: 1 Sec   内存限制: 128 MB
[ 提交][ 状态][ 讨论版]

题目描述

GW 是ZUFE的神犇,有一天他想到一种神奇的变换,并且将它命名为GW变换

对于一个数字n,该变换后的值GW(n)为,先令X=n

第一步,如果X为个位数,GW(n)=X,否则执行第二步;

第二步,X的奇数位置的数字之和为a,偶数位置的和为b, X=a*b, 执行第一步;

现在我们有T个询问,对于每个询问输入三个整数数l,r,x

对于每个询问请输出在[l,r]这个闭区间里的数经过该变换后为x的数有多少个

输入

第一行是一个T,表示有T组询问(T<=1000)

接下来T行,每行三个整数l,r,x (0<=l<=r<=10000000)

输出

输出T行,每行一个整数,代表着答案。

样例输入

2
1 10 2
20 25 0

样例输出

1
2

题解:分块+暴力
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int num[10100];
int count_num[10010][10];   //将10000000划分为10010组,每组1000个
char str_int[30];
int sum1,sum2;
 
void divid(int n){
    sum1=0,sum2=0;
    int flag=false;
    while(n>0){
        if(flag)
            sum1+=(n-n/10*10);
        else
            sum2+=(n-n/10*10);
        if(flag)
            flag=false;
        else
            flag=true;
        n/=10;
    }
}
 
int main(){
    int cnt=0;
    for(int i=0;i<=9;i++){
        num[i]=i;
        count_num[cnt][num[i]]++;
    }
    for(int i=10;i<=10000;i++){
        divid(i);
        num[i]=num[sum1*sum2];
        count_num[cnt][num[i]]++;
        if(i%1000==999)
            cnt++;
    }
    for(int i=10001;i<=10000000;i++){
        divid(i);
        int x=num[sum1*sum2];
        count_num[cnt][x]++;
        if(i%1000==999)
            cnt++;
    }
    int T;
    scanf("%d",&T);
    int l,r,k;
    while(T--){
        scanf("%d%d%d",&l,&r,&k);
        int ans=0;
        int i,j;
        int flag=0;
        if(k<0||k>=10){
            printf("0\n");
            continue;
        }
        for(i=l;i<=r;i++){
            if(i%1000==0)   //找到第一个是1000的倍数
                break;
            if(i==r)
                flag=1;
            if(i<=10000){
                if(num[i]==k)
                    ans++;
            }
            else{
                divid(i);
                int x=sum1*sum2;
                if(num[x]==k)
                    ans++;
            }
        }
        if(flag==1)
            printf("%d\n",ans);
        else{
            int start=i/1000;   //从第几个1000开始
            for(j=start;;j++){
                if((j+1)*1000-1>r)  //如果结尾超过r
                    break;
                ans+=count_num[j][k];
            }
            for(i=j*1000;i<=r;i++){
                if(i<=10000){
                    if(num[i]==k)
                        ans++;
                }
                else{
                    divid(i);
                    int x=sum1*sum2;
                    if(num[x]==k)
                        ans++;
                }
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}


你可能感兴趣的:(第九届浙江财经大学信息学院大学生程序设计竞赛)