[ACM] 2017 SCNUPC
来源:互联网 发布:动态桌面的软件 编辑:程序博客网 时间:2024/06/05 00:52
Problem A
cgy太喜欢质数了以至于他计数也需要用质数表示!在他看来,2(第一小质数)表示1,3(第二小质数)表示2……可正因为他的计数方法太奇葩,所以他的数学成绩非常差而且拖累了他的绩点。lxy得知cgy的绩点排名之后打算告诉他,可是必须以极度麻烦的cgy质数计数法的方式表示。lxy出重金 ¥(10000000 mod 10) 请你来为他解决这个诡异的计数。
Sample Input
1
2
28
13
Sample Output
2
3
107
41
抄了一个素数的打表
结果还看不懂(x)
//问题://没见过这个打表的算法//结果n设置出错//算法里应该是素数的上限我写成了输入的上限#include <algorithm>#include <cmath>#include <cstring>#include <iostream>using namespace std;int n;bool visit[ 10100000 ];int prime[ 10000000 ];void init_prime () { memset ( visit, true, sizeof ( visit ) ); int num = 0; for ( int i = 2; i <= n; ++i ) { if ( visit[ i ] == true ) { num++; prime[ num ] = i; } for ( int j = 1; ( ( j <= num ) && ( i * prime[ j ] <= n ) ); ++j ) { visit[ i * prime[ j ] ] = false; if ( i % prime[ j ] == 0 ) break; } }}int main () { n = 10000000; init_prime (); int i; while ( ~scanf ( "%d", &i ) ) { printf ( "%d\n", prime[ i ] ); } return 0;}
Problem B 数发票
cgy组织了某外出活动准备到学院报销,学院给了他一定的差旅费报销金额。而cgy平时是一个十分注重收集公交车发票的人,他的手上有无数张不同面值的发票,现在他想计算最少要多少张发票可以恰好达到报销金额。cgy忙着整理这些发票,于是把这个任务交给了一起外出的你,你需要仔细计算否则就拿不到外出的车费了。
输入
输入第一行是一个正整数T表示数据组数。接下来是多组数据,每组数据第一行是正整数n,分别表示cgy有n种面值的发票(每种都有无数张),接下来一行有n个由空格隔开的正整数,表示这n种面值的大小,再下一行是一个正整数x表示报销金额。(T,x<=1000;n<=100)
输出
对于每一组数据,输出能凑齐报销金额的最少的发票张数,如果不能正好凑齐则输出-1。
样例输入
2
3
1 3 5
11
2
3 5
7
样例输出
3
-1
动态规划……
dp[ i ] = min (dp[ i - coin[ j ] ] + 1,dp[ i ] )
#include <iostream>#define maxn 0x3f3f3f3fusing namespace std;int n;int coin[ 1000 ];int dp[ 1005 ]; //存储当前钱数需要的最少纸币个数void dp_fun ( int num ) { dp[ 0 ] = 0; //枚举1--所求的钱数 for ( int i = 1; i <= num; ++i ) { dp[ i ] = maxn; //枚举每个硬币 for ( int j = 0; j < n; ++j ) { //小于一个的不列举 if ( coin[ j ] > i ) continue; //这里傻了,写成了break // 加上钱后取最小 if ( dp[ i - coin[ j ] ] + 1 < dp[ i ] ) dp[ i ] = dp[ i - coin[ j ] ] + 1; } }}int main () { int T; scanf ( "%d", &T ); while ( T-- ) { scanf ( "%d", &n ); for ( int i = 0; i < n; ++i ) scanf ( "%d", &coin[ i ] ); int num; scanf ( "%d", &num ); dp_fun ( num ); if ( dp[ num ] == maxn || num == 0 ) printf ( "-1\n" ); else printf ( "%d\n", dp[ num ] ); } return 0;}
Problem C ljc吃糖
题目描述
ljc 喜欢吃糖,每一颗糖能够给他提供一个单位的脑能量。对于每道题,他至少要有 m1 能量才会考虑去做,且 AC 这道题需要消耗 m2 能量(即 ljc 能量数大于等于 m1 时才能去 AC 这道题,AC 完成后 ljc 剩余(当前能量值-m2)能量)。
现在 ljc 的初始能量为 n,比赛题目数为 k,问若 ljc 想要 AK (All-Killed,即 AC 所有题目),则他至少要准备多少颗糖?
输入
第一行输入一个正整数 T 表示数据组数,每组第 1 行两个数 n, k,接下来 k 行为两个正整数 m1, m2。
保证所有数据 T, n, k, m1, m2≤1000,且 m1 ≥m2 。
输出
每组数据占一行,输出 ljc 至少要准备的糖的数目。
样例输入
1
0 8
4 2
6 4
8 6
10 8
12 10
14 12
16 14
18 16
样例输出
74
贪心…吧hhh每次取差最小的那个就好了
#include <algorithm>#include <cstring>#include <iostream>using namespace std;int n, k;struct Work { int m1, m2; bool operator< ( const Work w ) { return ( m1 - m2 ) > ( w.m1 - w.m2 ); }} work[ 1002 ];int greedy () { int candy = 0; for ( int i = 0; i < k; ++i ) { if ( work[ i ].m1 > n ) { //这里判断的情况少了一点点 candy += work[ i ].m1 - n; n = work[ i ].m1 - work[ i ].m2; } else n -= work[ i ].m2; } return candy;}int main () { int T; scanf ( "%d", &T ); while ( T-- ) { scanf ( "%d%d", &n, &k ); for ( int i = 0; i < k; ++i ) scanf ( "%d%d", &work[ i ].m1, &work[ i ].m2 ); //不小心写到循环外面去了 sort ( work, work + k ); int sol = greedy (); printf ( "%d\n", sol ); } return 0;}
Problem D 姓名字母排列
题目描述
自古以来,如果如何排列一份无序名单是一个具有争议性、颇为麻烦的问题。通常的做法是按照姓名拼音的英文字母排字典序。
某一天 Zyj 突发奇想,能不能把所有人的名字拼在一起成为一个串,并且这个串在所有拼接方案中字典序是最小的呢?比如有三个人的名字:zyh、zy、zyj,显然会有以下六种组合(加入空格是便于阅读,实际排列不应有空格):
zyh zy zyj
zyh zyj zy
zy zyh zyj
zy zyj zyh
zyj zyh zy
zyj zy zyh
显然只有第二种 zyhzyjzy 是所有方案中字典序最小的。
现在给你一份名单,你能找出这个最小方案吗?
输入
第一行输入一个正整数 N < 10^6代表名字数量。
接下来 N 行,每行输入一个只含小写字母的字符串(当然也不含空格),代表每个人的名字。
保证一个人的名字最大长度不超过 20 ,保证所有人名字长度的总和小于 10^6
输出
输出名字排列拼接方案,要在所有可行方案中满足字典序最小。
样例输入
3
hello
world
zyj
样例输出
helloworldzyj
不是很懂字典序,反正那么比较就是了
//对字符串排序,不过bba > bab#include <algorithm>#include <iostream>#include <string>using namespace std;//数组开小了RTE//声明为全局就不会Segmentation Fault(栈的大小不够)string strs[ 1000000 ];//正确的比较方式bool cmp ( string s1, string s2 ) { return ( s1 + s2 ) < ( s2 + s1 ); }int main () { int len; cin >> len; for ( int i = 0; i < len; ++i ) cin >> strs[ i ]; sort ( strs, strs + len, cmp ); for ( int i = 0; i < len; ++i ) cout << strs[ i ]; cout << endl; return 0;}
Problem E Substring
题目
一个字符串的子串表示原字符串中一段连续的部分。例如,字符串”121”的子串总共有六个,它们分别是”1”(前一个),”2”,”1”(后一个),”12”,”21”和”121”。但”11”不是”121”的子串,因为两个’1’在原串中不连续。我们认为空串也不是子串。
现给你一个只含有’0’和’1’两种字符的字符串,问它含有相同’0’和’1’的子串有几个。例如,字符串”0101”中符合条件的子串有4个。它们分别是”01”(前一个),”10”,”01”(后一个),”0101”。
输入
输⼊只有一行,为给定的字符串。字符串长度不超过100,且只包含'0'和'1'两种字符。
输出
输出为一个数,表示符合条件的子串的个数。注意最后有一个换行符。
样例输入
00110011
样例输出
10
暴力搜了……..
#include <cstring>#include <iostream>using namespace std;int n;char A[ 1000 ];int substring () { int cnt = 0; n = strlen ( A ); //比较所有的子串 for ( int i = 0; i < n; ++i ) for ( int j = 0; j < n - i; ++j ) { int c0 = 0, c1 = 0; for ( int k = j; k <= j + i; ++k ) { if ( A[ k ] - '0' ) c1++; else c0++; } if ( c1 == c0 ) cnt++; } return cnt;}int main () { scanf ( "%s", A ); int sol = substring (); cout << sol << endl; return 0;}
Problem F 法特狗
题目描述
众所周知,cgq因为脸黑而没有去玩法特狗这一款游戏,不过他老板gou4shi1经常问他某个英灵厉不厉害,为了一劳永逸,cgq决定写个程序给所有英灵打个分。在法特狗里,每张卡牌都对应着一个英灵。设nn为卡池里所有卡牌的数目,mm为卡池里有多少张卡牌y使得,英灵x的所有属性都大于等于英灵y的对应属性(注意,y可以是x本身),则英灵x的评分为 $\frac{m}{n}$现在认为每个英灵只有四个属性(耐久、敏捷、魔力、幸运),每个属性只有四个等级(ABCD,A最强,D最弱)。给出一个卡池所有英灵的属性,要求给所有英灵评分。
输入
输入第一行是一个整数n(1000001≤n≤100000),代表卡池里所有卡牌的数目。接下来是n行,每行四个大写字母,分别代表每个英灵的耐久、敏捷、魔力、幸运。
输出
输出n行,每行一个浮点数(小数点后保留两位),代表每个英灵的评分。
样例输入
4
AAAA
AAAD
CBCD
DDDD
样例输出
1.00
0.75
0.50
0.25
想了一些办法,刚开始想给每一列排序记录最大的位置,不过有漏洞…..
因为数据就四列,每个位置只有四种,所以最多256种就想到转换成四进制打表了….
然后遍历所有比它全小的可能,再加起来….
(感觉这里还是很暴力…出来的时间是48)
(做这道题的时候蛮开心的,做完了就再也不想写下去了hhh)
#include <algorithm>#include <cstring>#include <iostream>#define maxn 100005using namespace std;int val[ maxn ][ 5 ];int Forth[ 400 ];int sol[ 400 ];int Hash ( int i ) { return val[ i ][ 0 ] * 64 + val[ i ][ 1 ] * 16 + val[ i ][ 2 ] * 4 + val[ i ][ 3 ];}void Change ( char *ch, int i ) { for ( int j = 0; j < 4; ++j ) { val[ i ][ j ] = 4 - int( ch[ j ] - 'A' ); }}int main () { int n; char ch[ 4 ]; memset ( Forth, 0, sizeof ( Forth ) ); memset ( sol, -1, sizeof ( sol ) ); scanf ( "%d", &n ); for ( int i = 0; i < n; ++i ) { scanf ( "%s", ch ); Change ( ch, i ); Forth[ Hash ( i ) ]++; } for ( int i = 0; i < n; ++i ) { int t = Hash ( i ); if ( sol[ t ] != -1 ) { printf ( "%.2f\n", double( sol[ t ] ) / n ); continue; } else { int cnt = 0; int tmp[ 4 ]; for ( int k = 0; k < 4; ++k ) tmp[ k ] = val[ i ][ k ]; for ( int a = tmp[ 0 ]; a > 0; --a ) for ( int b = tmp[ 1 ]; b > 0; --b ) for ( int c = tmp[ 2 ]; c > 0; --c ) for ( int d = tmp[ 3 ]; d > 0; --d ) cnt += Forth[ a * 64 + b * 16 + c * 4 + d ]; sol[ t ] = cnt; printf ( "%.2f\n", double( sol[ t ] ) / n ); } } return 0;}
Problem G zyj打印奖状
题目描述
zyj又被叫去打印奖状啦!但是学院办公室的打印机实在太辣鸡,经常把奖状文字打歪。为了让学院更换打印机,zyj把自己在学院得的所有奖状都拿出来,用以展示这打印机打出来的奖状到底歪成什么样子。为了方便表示,zyj决定把每一张奖状的文字范围中心和奖状纸张中心的几何距离列举出来,用以表观地显示打印机的误差。zyj天天都要打印奖状,日理万机,所以他请求你帮他完成这个任务。
输入
zyj得的奖状数不胜数,所以输入文件包括若干组奖状数据。每组奖状数据包含两行,第一行是两个浮点数a,b(a,b>0),表示奖状的大小;第二行是四个浮点数x,y,l,w(x,y>=0;l,w>0),表示奖状上文字范围左上角的坐标和文字范围的长和宽。输入数据保证文字范围一定完全在奖状面积内。输入到文件结尾结束。
输出
对应每一组奖状数据输出奖状中心和文字区域中心的几何距离,保留3位小数。
样例输入
3.0 4.0
1.0 1.0 1.0 1.0
2.0 2.0
1.0 1.0 1.0 1.0
3.0 3.0
0.0 0.0 3.0 3.0
样例输出
0.500
0.707
0.000
emmmm浮点数输出
#include <math.h>#include <stdio.h>int main () { int i = 0; double a, b, x, y, l, w; while ( scanf ( "%lf%lf", &a, &b ) != EOF ) { double v = 0.0; scanf ( "%lf%lf%lf%lf", &x, &y, &l, &w ); v = sqrt ( ( ( x + l / 2 ) - ( a / 2 ) ) * ( ( x + l / 2 ) - ( a / 2 ) ) + ( ( y + w / 2 ) - ( b / 2 ) ) * ( ( y + w / 2 ) - ( b / 2 ) ) ); printf ( "%.3f\n", v ); i++; } return 0;}
Problem H CG之争
题目描述
众所周知,cgq和cgy名字中只差一个字。为了保住CG这个名号,cgq作为擂主给cgy出了个难题:要是cgy能在1s内答出
输入
多组数据,每一组一行是cgq给出的一个正整数n,输入到文件结尾结束。(n<=80)
输出
对应于每一组n求出
样例输入
1
2
样例输出
1.000
1.000
斐波那契数列
#include <iostream>using namespace std;// 80超过了intlong long Fibonacci[ 100 ];void Compute () { Fibonacci[ 0 ] = Fibonacci[ 1 ] = 1; for ( int i = 2; i < 81; ++i ) { Fibonacci[ i ] = Fibonacci[ i - 1 ] + Fibonacci[ i - 2 ]; }}int main () { int n; Compute (); while ( ~scanf ( "%d", &n ) ) { printf ( "%lld.000\n", Fibonacci[ n - 1 ] ); //输出少了个0..... } return 0;}
Problem I 人形质量单位
题目描述
每个人的质量或许相同,或许不同。于是乎,如果以人们的体重作为一个计量单位,那么可以有多少种不同的组合呢?
设有n(1<=n<=10)种不同的质量,第i种质量大小为wi,第i个质量有xi个人(其总重量不超过300000kg),要求编程输出这些人形能称出不同质量的种数,但不包括一个人也不用的情况。
输入
第一行输入质量的种数n第二行输入每种质量的质量第三行输入每种质量的人的人数
输出
输出可以称量的质量种数
样例输入
3
1 2 3
2 1 2
样例输出
10
dfs + 剪枝
似乎时间也没有特别好
#include <cstring>#include <iostream>using namespace std;int n;int w[ 12 ], x[ 12 ];int cnt = 0;bool vis[ 300005 ];bool vis2[ 10 ][ 300005 ];void dfs_mb ( int i, int curval ) { if ( i == n ) return; else { for ( int k = 0; k <= x[ i ]; ++k ) { int nex = curval + w[ i ] * k; if ( !vis[ nex ] ) cnt++, vis[ nex ] = true; //同一深度找到了相同的数就忽略掉 if ( !vis2[ i ][ nex ] ) { dfs_mb ( i + 1, nex ); vis2[ i ][ nex ] = true; } } }}int main () { scanf ( "%d", &n ); for ( int i = 0; i < n; ++i ) scanf ( "%d", &w[ i ] ); for ( int i = 0; i < n; ++i ) scanf ( "%d", &x[ i ] ); memset ( vis, false, sizeof ( vis ) ); memset ( vis2, false, sizeof ( vis2 ) ); dfs_mb ( 0, 0 ); printf ( "%d\n", cnt - 1 ); return 0;}
题目描述
L2M 未来科技开发公司研制了一款新的智能机器人 ZetaGo ,它可以把任何事物都计算出一个特征值,在经过重排后可以据此做出一系列的决策。
为了检验 ZetaGo 的重排能力,需要人工进行监督学习(supervised learning)训练。 LLM 作为 L2M 手下的一名实验员,就要每天进行这样的苦差事。
今天的重排规则是这样的:已知一组特征值 A ,要求重新排列后的组合 B 可以满足任意两个相邻元素的乘积(
今天 LLM 实在太累啦,想拜托你帮帮忙。
输入
第一行输入一个正整数 T≤10 代表着训练组数。
接下来 3T 行,每 3 行首先是一个正整数 2≤N≤1000 代表着特征值的个数,接下来一行是用空格隔开的特征值
输出
请你告诉 ZetaGo 它的判定结果对不对,输出 "AC" 或者 "WA" 表示对或错(不包括引号)。
样例输入
3
2
4 4
no
3
1 2 4
yes
4
1 2 2 4
yes
样例输出
WA
AC
AC
分三种
四的倍数,二的倍数但不是四的,奇数
二倍不存在,必须四倍>奇数个数
二倍存在,四倍>=奇数
#include <iostream>using namespace std;int n;int Forth, Twice, Odd;int val[ 1000 ];void Classify ( int v ) { if ( v % 4 == 0 ) Forth++; else if ( v % 2 == 0 ) Twice++; else Odd++;}bool Judge () { if ( Twice == 0 ) { if ( Forth >= Odd - 1 ) return true; else return false; } else { if ( Forth >= Odd ) return true; else return false; }}int main () { int t; scanf ( "%d", &t ); while ( t-- ) { scanf ( "%d", &n ); Forth = Twice = Odd = 0; for ( int i = 0; i < n; ++i ) { scanf ( "%d", &val[ i ] ); Classify ( val[ i ] ); } bool flag = Judge (); char ch[ 4 ]; scanf ( "%s", ch ); if ( ch[ 0 ] == 'n' && !flag ) printf ( "AC\n" ); else if ( ch[ 0 ] == 'y' && flag ) printf ( "AC\n" ); else printf ( "WA\n" ); } return 0;}
Problem K 强迫症患者
题目描述
cgy是一个很有强迫症的人,他一看到小数就浑身难受。然而有一天,他碰到了这么一条只有整数和除号构成的式子:1/2/4/16 ,他的强迫症又来了,加上了括号让式子变成了 (1/2)/(4/16)=2 把它变成了整数。但是走着走着,他又碰到了一个墙上写满了这个风格的式子,cgy突然发现有些式子可以通过加括号来让结果变为整数,有些却不行。但是他手边没有纸和笔,于是就没有把这个想法写下来,现在你能通过这一系列数字来判断他们是否可以通过加括号变成整数么
输入
一个整数n(n<=100)表示有几组数据接下来输入m(m<=1000)表示有m个数字,再下去一行输入m个正整数(每个数字不大于1000),表示式子中的数字
输出
对于每一行输入,如果可以通过加括号变成整数就输出Yes,否则输出No。
样例输入
3
3
1 2 4
4
1 5 6 9
4
1 4 2 2
样例输出
Yes
No
Yes
我是一个还没入门的人
洛谷 P2651 添加括号III 题解
[贪心 入门题] 洛谷 P2651 添加括号III
Problem L Oyk 捏泡泡纸
题目描述
著名的剪纸大师 Oyk 今年不剪纸了,最近工作压力大,他改为捏泡泡纸来放松心情。由于 Czj 每天上班摸鱼,他被抓过来陪 Oyk 捏泡泡纸。
已知一张完好的泡泡纸上会有 NN 个泡泡,他们约定每次每个人都可以 paji 掉 2 的幂次(1,2,4,8,16,…,
看他们捏泡泡太无聊了,我想预先知道他们谁能够刚好在最后捏完整张泡泡纸。
输入
可能会有多行输入,请你一直处理到文件尾。
每行会输入一个正整数
输出
对于每张泡泡纸,请你告诉我故事的结局。如果是 Oyk 最后捏完,输出 "Oyk Oyk!" (不包括引号,下同)。如果是 Czj 最后捏完,输出 "diu,Czj!" 。
样例输入
4
5
6
样例输出
Oyk Oyk!
Oyk Oyk!
diu,Czj!
发现规律后只是3的倍数
#include <algorithm>#include <iostream>typedef long long LL;using namespace std;int m;int maxval = 0;int val[ 1005 ];bool ok () { for ( int i = 0; i < m; ++i ) if ( maxval % val[ i ] ) return false; if ( val[ m - 1 ] % val[ m - 2 ] ) return false; return true;}int main () { int n; scanf ( "%d", &n ); while ( n-- ) { scanf ( "%d", &m ); maxval = 0; for ( int i = 0; i < m; ++i ) { scanf ( "%d", &val[ i ] ); maxval = max ( maxval, val[ i ] ); } int flag = ok (); if ( flag ) printf ( "Yes\n" ); else printf ( "No\n" ); } return 0;}
Problem M 光棍节活动
题目描述
一年一度的光棍节活动中,cgy 的班级想搞一个别出心裁的活动,要求将班上的男生和女生完美分组,规则如下:
1. 每个组之间男生数要相同,女生数也要相同;
2. 同一个组中的男生数不能等于女生数;
3. 每组中男生或女生要有 2 名或以上(即不能只有一男一女);
4. 必须要分成 2 个或以上的组,组数也要尽可能的多才好玩;
如果不能完美分组,将随机抽出一名男生和一名女生组成一队进行假扮情侣活动,重复进行(尽量少的次数)抽人直到剩下的男女生人数恰好可以完美分组。
如果始终不存在完美分组,那么除了成功组队进行假扮情侣的外,可能会多出若干男生或者女生没有组队哦(同性才是真爱!)。
cgy 安排 lxy 实施这个方案,但 lxy 脸红心跳,想请你帮帮忙。
输入
第一行输入正整数
接下来 T 行,每行包含两个正整数
输出
对于每种情况,请你帮忙计算出完美分组数和假扮情侣数,在一行中输出,用空格隔开。
如果存在没有组队的幸运儿,你可以再为 ta 们输出且只输出一行 “happy single dog!” (不包括引号)聊表庆祝。
样例输入
3
18 24
19 25
18 19
样例输出
6 0
6 1
0 18
happy single dog!
最大公因数,按照要求判断就行了
输出时读题不仔细,没有剩下的人不用happy single dog
(对了…某学霸两周前脱单了….一阵暴击hhhh)
#include <iostream>int gcd ( int a, int b ) { int t; while ( b ) { t = b; b = a % b; a = t; } return a;}bool judge ( int a, int b, int c ) { if ( a / c == b / c ) return false; if ( ( a / c < 2 ) && ( b / c < 2 ) ) return false; if ( c < 2 ) return false; return true;}int main () { int T; scanf ( "%d", &T ); while ( T-- ) { int a, b; scanf ( "%d%d", &a, &b ); int flag = 0; int pair = 0; int c; while ( a && b ) { c = gcd ( a, b ); if ( judge ( a, b, c ) ) { flag = 1; break; } --a, --b, ++pair; } if ( flag ) printf ( "%d %d\n", c, pair ); else { printf ( "0 %d\n", pair ); if ( a || b ) printf ( "happy single dog!\n" ); } } return 0;}
- [ACM] 2017 SCNUPC
- acm 2017
- ACM-2017
- 杭州电子科技大学acm--2017
- 2017 山东acm省赛
- ACM
- acm
- ACM
- acm
- ACM!!
- ACM!!
- acm
- ACM
- ACM
- acm
- acm
- ACM
- ACM
- Java开发中的23种设计模式概述
- angular.js中的$q
- 机器学习之理解支持向量机SVM
- 自然语言处理入门资料推荐
- SQL Server 2008数据库创建,备份,还原图解及注意事项
- [ACM] 2017 SCNUPC
- Unity3D Shader——水的折射
- html5 的手机触摸事件注意事项
- 再次修复,双系统找回 Windows 启动引导
- JVM:查看java内存情况命令
- 辞职了要不要退微信群,如果要,如何“优雅地退群”?
- 第一篇博客
- 请多指教
- ###逆向工程的Example类用法==注意:【没写example.createCriteria();执行selectByExample(example)表示:查询全部】