sc测试二
来源:互联网 发布:网络服务器托管 编辑:程序博客网 时间:2024/06/06 20:49
在这组测试题中罕见地发现了水题,先从这题开始说起。
打印机
题目描述
打印机
有一台打印机,它能打出一张像素为n×m的图片(可以把图片想象为一个n行m列的表格)。一开始所有像素点都是0号颜色。我们将对图片依次进行k次绘制操作,有两种操作:
把第r行的所有像素都绘制成c号颜色。
把第c列的所有像素都绘制成c号颜色。
你需要计算打印机打印出来的图片的每个像素点的颜色。
输入格式
第一行三个整数n, m, k。 n, m, k ≥ 1
接下来k行,每行三个整数x, i, c表示一个操作(c ≥ 1):
如果x=1,那么表示把第i行的所有像素都绘制成c号颜色。
如果x=2,那么表示把第i列的所有像素都绘制成c号颜色。
输出格式
n行,每行m个表示颜色编号的整数。
输入样例
3 3 3
1 1 3
2 2 1
1 2 2
输出样例
3 1 3
2 2 2
0 1 0
这题现在的我会做,相信未来的我也会做。把每一行与每一列涂色的时间记录下来。我想过如果有一行重复染色怎么办,事实证明后染者会覆盖掉。
代码如下:
#include#include using namespace std;int x,f,c,n,m,k;struct ee{int num,time;}h[100005],z[100005];int main(){freopen("2100.in","r",stdin);freopen("2100.out","w",stdout);cin>>n>>m>>k;for(int i=1;i<=k;i++){cin>>x>>f>>c;if(x==1) {h[f].num=c;h[f].time=i;}else {z[f].num=c;z[f].time=i;}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(h[i].num!=0&&z[j].num!=0){if(h[i].time
假期/放假
题目描述
经过几个月辛勤的工作,FJ决定让奶牛放假。假期可以在1…N天内任意选择一段(需要连续),每一天都有一个享受指数W。但是奶牛的要求非常苛刻,假期不能短于P天,否则奶牛不能得到足够的休息;假期也不能超过Q天,否则奶牛会玩的腻烦。FJ想通过安排一次假期,奶牛们获得的享受指数(假期内每天的享受指数之和)最大。
50% 1≤N≤10000
100% 1≤N≤100000
1<=P<=Q<=n
输入格式 2136.in
第一行:N,P,Q.
第二行:N个数字,中间用一个空格隔开。
输出格式 2136.out
一个整数,奶牛们能获得的最大享受指数。
输入样例 2136.in
5 2 4
-9 -4 -3 8 -6
输出样例 2136.out
5
(选择第3-4天,享受指数为-3+8=5。)
当时的情况:
把所有题目浏览了一遍以后,发现才半小时,有很多同学都AC了这题,以为是超级大水题。用简单的思路研究了半天,结果用简单的加加减减,没有什么用,终究逃不出n^2。
正解:
部分和+单调队列。题目棘手的地方主要是规定了段的长度,并且这个长度不是一个定值,并且这个长度在一定的范围以内。
这样就起到单调队列的作用了,当对头的坐标超过这一段的距离便把它踢出去。算出每一段的部分和。枚举到,如果当前这一段的部分和比单调队列队尾的小,便存进去,保持一个单调下降序列。最后用枚举到的i,减去队列头(既部分和最小的某段),就是正确答案。
为什么要这么做呢?因为用当前的部分和sum[i]减去最小的,设为k,那么k+1~i这一段便是最大值。
为了符合题目条件中要满足一段中数的个数大于p,for循环枚举从p开始。
关于题目的某些梗:
在比赛结束以后,终于弄清楚了他们那么快提交的原因。原来是前一天单调队列专题里的某题,于是,复制粘贴?无奈我做太慢。
代码如下:
#include#include using namespace std;int n,q,p;long long k[100005],ans=100000000000000,sum[100005],a[100005];int main(){freopen("2136.in","r",stdin);freopen("2136.out","w",stdout);ios::sync_with_stdio(false);cin>>n>>p>>q;for(int i=1;i<=n;i++) {cin>>a[i];sum[i]=sum[i-1]+a[i];}ans=-ans;int head=1,tail=0;for(int i=p;i<=n;i++){while(head<=tail&&sum[k[tail]]>=sum[i-p]) tail--;tail++;k[tail]=i-p;while(head<=tail&&k[head]
Bug2
题目描述
Bug2
之前的战斗使虫族的建筑遭到破坏,Bug需要组织大家一起重建被破坏的建筑。不过,为了合理分配任务,他需要仔细地考虑虫族的关系网络。
虫族的基地组织是一棵有根树,基地可看作是树的节点。每个基地i都有自身的影响力ai。树的边有一定的长度,记dis(u,v)表示基地u和基地v的距离。
关系网络的复杂性体现在两个基地可能会有控制的关系,我们说基地u控制基地v当且仅当:
u是v的祖先;
且dis(u,v)≤aV。
//注意是child能影响到father,father才能控制child
Bug为了合理分配每个基地的任务,需要了解每个基地控制多少个基地。作为虫族总参谋,你能帮帮他吗?
输入格式
第一行一个正整数N,表示基地的个数。
第二行N个整数,第i个表示ai。1 ≤ ai ≤ 109。
接下来N-1行,每行两个整数a,b。输入的第2+i行,表示基地i+1和基地a之间有一条边,且边的长度为b。1 ≤ a ≤ i;1 ≤ b ≤ 109。
输出格式
一行,N个整数,第i个表示基地i控制多少个基地。
输入样例1
5
2 5 1 4 6
1 7
1 1
3 5
3 6
输出样例1
1 0 1 0 0
输入样例2
5
9 7 8 6 5
1 1
2 1
3 1
4 1
输出样例2
4 3 2 1 0
测试点
N
1~2
≤1 00
3~4
≤1 000
5~10
≤100 000
前言:
前面送上两个稍微比较水的题目,接下来的题就不是那么简单的了。
题目大意:
题目比较复杂,我一直理解错题目的意思,1、以为是要由能够影响到即可控制对方 2、以为是由祖先影响到child才行。
实际上,是由child能影响到祖先,才可以。
在比赛的时候,我已经被绕晕了。
部分分:
60分 暴力(无差分)。
正解:
跑一次dfs,把经过的点加入栈,这样一来,就可以保证栈里面的数都是当前now的祖先。在这里,可以用二分来找到可以影响到哪些祖先。越早入栈的祖先就越距离越远。如图:
1一定会比2先入栈,而距离3越远的也是1。所以可以用二分找到距离最远的可以影响到的祖先。假设图中3最远可以影响到1,于是给2和1的ans++。由于数据范围,如果经过这样子逐个增加,一定会超时。
有一种很特别的方法,举个例子:加入有n个篮子,要在第2~4个篮子里放一个水果 , 再在第3~7个篮子里放多哦一个水果。
有什么好办法呢?我们先在2篮子那里标记为1,意思为后面的都加上1,可是这样4以后的数字就都不符合题意了,所以在5的地方标记-1。同理在3的地方标记为1,8标记为-1。
在这样的基础上,扫一次for循环,求sum,会有什么样的结果呢?
正好是每个篮子的果子数。成功地把O(n^2)优化为O(n)。
同样的,也可以用这种方法算出每一个点被几个点影响到。在最近的可以被影响到的点+1,在最近的不可以被影响到的点-1。
最后再跑一次dfs,计算出正确的ans即可。
另一种方法:
前面所说的二分是yhf同学的方法,lhf同学还讲了一种倍增法,但是我不是很能理解,倍增的时间复杂度比较高。
PS:
纠正一下,听同学lkb说,倍增的时间复杂度其实是差不多的,并且倍增的方法是通用的,而栈的方法有些题目不一定适用
#include#include #include using namespace std;const int maxn=100005;long long x,y,nowsum,n,num,p[maxn],a[maxn],ans[maxn],sum[maxn],k[maxn];bool vv[maxn];struct tt{int to,l;};vectorq[maxn];void dfs(long long now,long long from){if(now!=1){a[++num]=from;int lo=0,hi=num+1;while(lo+1 >n;for(int i=1;i<=n;i++) cin>>p[i];for(int i=2;i<=n;i++){cin>>x>>y;q[x].push_back(tt{i,y});}dfs(1,0);for(int i=1;i<=n;i++) vv[i]=false;dfs2(1);for(int i=1;i<=n;i++) cout<
圆括号
题目描述
慧音正在教妹红什么是合法括号序列:
①空字符串是一个合法括号序列。
②如果X和Y都是合法括号序列,那么XY(即字符串Y拼在字符串X的后面所组成的新的字符串)是一个合法括号序列。
③如果X是合法括号序列,那么 (X)也是合法括号序列(即在X的左边加一个左括号,右边加一个右括号)
所有的合法括号序列都可以用①~③的规则所构造出来。
现在妹红得到了两个括号序列(注意,不一定合法),记为X和Y,她想构造出一个新的括号序列Z。她每一次会将X或Y的最左边的字符加进Z的末尾,然后将其从X或Y中删去,直到X与Y都为空。她问慧音有多少种选择方案可以让Z是一个合法括号序列。两种选择方案不同是指至少存在一个位置k,使得第一种方案中Z的第k位从X得来,而在第二种方案中Z的第k位从Y得来(不是指两种方案的Z不同)。方案数mod 1000000007(10^9+7)
妹红觉得很好玩,于是她决定再随机生成偶数个括号序列,向慧音多次询问(即多组测试数据)。然而慧音并不知道怎么做,于是她交给了学OI的你。
输入格式 1989.in
第一行一个整数T,表示询问组数。
接下来每组询问有两行,每行一个字符串,分别代表题目中的X和Y。
输出格式 1989.out
共T行,每行一个整数,代表生成合法括号序列的方案数。
输入样例 1989.in
6
(()
())
(
)
(((((
)))))
()(()
))((())
()()()()()()()()()()()()()()()
()()()()()()()()
())())))
))((((
输出样例 1989.out
19
1
42
10
493841617
0
第一组询问的19种方法:红色代表来自X,蓝色代表来自Y。
【数据范围】
T<=8,X,Y长度不超过50。
当时的情况:
看到这题就懵逼了,一直没有理解什么是合法括号序列。题目似乎也没有明确说呀。。说白了就是没怎么看懂题目。后来wyy给我解释,所谓的合法括号序列就是每一个左括号都有一个右括号可以对应。
即使知道了题目的意思,但还是比较蒙,就算是用暴力也不知道该从何下手为好。
正解:
DP。是一个比较简单的DP,但是对于我这个DP很差的人来说,还是比较困难。f[i][j]表示的状态为,从第一个字符串里面选i个从第2个字符串里面选j个的方案数,并且保证左括号的
数量比右括号的多。
可以设一个a记录左括号的数量,设一个b记录右括号的数量,如果左括号的数量比右括号的小,那么这个状态是不合法的,方案数为0,continue。
状态转移方程为f[i][j]=f[i-1][j]+f[i][j-1]。就是可以由第一个字符串取也可以由第二个字符串取。
注意:
但是注意,在双重for循环中,扫过一次j,但是在第二次for循环会重复添加第二个字符串的左括号数量和右括号数量。所以,每一次外围(i)for循环结束以后,再扫一次j(第二个字符串),再减回刚刚加过的部分,这样子就不会影响到后面了。
或者也可以用部分和的方法记录括号的数量,我没试过。
代码如下:
#include#include #include #include using namespace std;int r,a,b;long long f[55][55];const int mod=1000000007;string x,y;int main(){freopen("1989.in","r",stdin);freopen("1989.out","w",stdout);cin>>r;while(r){r--;int a=0,b=0;cin>>x>>y;for(int i=0;i<=x.size();i++)for(int j=0;j<=y.size();j++) f[i][j]=0;f[0][0]=1;int size1=x.size(),size2=y.size();for(int i=0;i<=size1;i++){if(i>=1){if(x[i-1]=='(') a++;else b++;}for(int j=0;j<=size2;j++){if(i==j&&j==0) continue;if(j>=1){if(y[j-1]=='(') a++;else b++;}if(a=1) f[i][j]=(f[i-1][j]+f[i][j])%mod;if(j>=1) f[i][j]=(f[i][j]+f[i][j-1])%mod;}if(i!=size1){for(int j=1;j<=size2;j++){if(y[j-1]=='(') a--;else b--;}}}if(a==b) cout<
魔法练习
题目描述
在第四届圣杯之战中,时臣其实是预见到麻婆和金闪闪会背叛他的。所以在正式开战前,时臣决定传授祖传宝石魔法给凛,就给了凛魔法图鉴。
在魔法图鉴中,每条魔法都有一个密钥,是一个由“(”、“)”和“?”组成的魔法符文。时臣同时教凛密钥的破解方法:对于第i个为“?”的符文,可以输入魔力使其变为“(”,或输入的魔力使其变为“)”。只要最终魔法符文都变为合法,匹配的括号符文,就可以瞬间学会该魔法。
凛当然想学会全部魔法,但她还是个小萝莉,魔力有限,她希望,能用最小的魔力,学习全部的魔法(使符文变成合法的括号匹配序列)。
对于40%的数据,n ≤ 100
对于60%的数据,n ≤ 1000
对于100%的数据,n ≤ 100000,n为偶数(n为字符串的长度)
输入格式 2088.in
这题目包含多组测试数据(不超过10组)。
每组测试数据,第一行为一个没有空格,偶数长度的字符串,保证由“(”、“)”和“?”组成,长度不超过100000。然后接下来的m行(m为字符串中“?”的个数),每行有两个整数Ai和Bi,(1≤Ai,Bi ≤1000000),分别代表将第i个符文转换为“(”和“)”所需的魔力。
输出格式 2088.out
若有解,输出所需最小魔力;若无解,输出-1。
输入样例 2088.in
(??)
1 2
2 8
输出样例 2088.out
4
部分分:
60分 DP
部分分做法:
之所以要讲部分分做法,是因为这个做法不是水分,还是有点意思的。
和上一题的做法有点相似,两题有所关联。状态f[i][j]为已经选了前i位,左括号与右括号的差为j。很容易得出状态转移方程:现在取左括号与现在取右括号的min。
取左括号的情况为f[i-1][j-1]+a[i](因为左括号多了一个,所以左右两个的差值要减一)右括号:f[i-1][j+1]+b[i] 两边的值取Min。
然而,我还没写出代码,代码略。
讲解后的自行探索:
我试过两种,不过有一种没有成功,也就是在完成正解之前的一种有漏洞的方法。
先把所有题目给出的括号置为‘?’,并把所有的左括号都弄为0,右括号置为oo,一路扫下来,用线段树保存前一段中左括号的最小值。同样是用a记录左括号的个数,用b记录右括号的个数。
如果当a>=b时,无论左右括号哪个比较小,都是可以选的。但是如果a<b,那么一定只能选左括号,于是用for循环看看前面最小的左括号。
看似很靠谱,但是到最后是无法保证左括号的个数和右括号的个数相等。
正解:
贪心+优先队列。参考了同学的方法,由于步骤太过于繁琐,标号比较明确。
1、可以不必把所有括号置为‘?’。
2、在输入的时候,用k数组记录下左括号数(a)减去右括号数(b)的差值。
3、假设所有的都为右括号,先把ans加上所有的b。
4、再开一个临时变量x,为当前ab的差值。
5、开一个小根堆xiao。
6、是左括号x++,右括号反之。如果是问号,便把当前这组问号ab(k)的差值存进小根堆里。
7、如果此时左括号已经比右括号少了,即x=-1,那么便要从前面的问号,也就是小根堆里面存的值里取一个最小的差值加入ans,而小根堆中的top,就是最小的值。
8、验证一下这样加的正确性:小根堆中存的是问号的k=a-b,而ans一开始是所有b的总和,ans+k=ans+a-b,正好是加上左括号的值,同时把原来ans中存有的右括号消去。
9、如果此时优先队列为空,也就是说明前面没有问号,那么直接return ans=-1。否则,做上面的加法运算。记得把x改为1。为什么是改为1而不是0,举个例子就可以知道了。本来的a=2,b=3,x=-1;后来改为a=3,b=2,x=1。
10、被修改的括号就失去了价值,弹出优先队列
11、最后还有一种特殊情况,即为全部改完以后,a和b不相等,此时也是不合法的。如果没有加这个特判,只有90分。
除此之外,也可以用线段树,不过线段树比优先队列更为繁琐,所以我也没有写对。
#include#include #include #include #include #include using namespace std;const int maxn=100005;long long a,b,ans,c,size,k[maxn];string s;priority_queue , greater > xiao;//小根堆 void solve(){int x=0,c=0;for(int i=0;i >s){size=s.size();ans=0,c=0;memset(k,0,sizeof(k));while(!xiao.empty()) xiao.pop();for(int i=0;i >a>>b;k[++c]=a-b;ans+=b;}}solve();cout<
- sc测试二
- sc测试一
- sc测试四 赛后感受
- sc测试八赛后感受
- SC
- sc
- SC命令可以用来测试你自己的系统
- AutoExcuteJob Framework(二)再谈Windows Service:SC 和 InstallUtil 区别
- AutoExcuteJob Framework(二)再谈Windows Service:SC 和 InstallUtil 区别
- VC中PC/SC智能卡接口的编程(二)
- AttributeError: 'NoneType' object has no attribute 'sc' 解决方法(二)
- 测试二
- 测试二
- spark安装测试过程中提示<console>:10: error: not found: value sc
- SC 命令
- 打SC
- sc命令
- SC命令
- New Document
- 山东省第八届 ACM 省赛 sum of power(SDUT 3899)
- Bootstrap基础日期控件使用
- PHP将数据库中的表导成.sql文件
- 2017暑假集训总结
- sc测试二
- 从头开始学java之新人求罩~(二) 第一步 初识java和环境搭建
- 幻数
- struct中的数组和指针
- 解释一下负载均衡原理
- spring_boot
- 剑指offer面试题4 替换空格
- JavaScript的操作数组的函数
- 【框架学习】Mybatis简解