在大神的指引下,第一次真正意义上“打”了一次cf,虽然惨惨哒,但还是有收获。
A. Wizards' Duel
题中说明碰撞后按相反方向原路返回,虽然两次碰撞,但本质为相遇问题。
100
50
50
50
199
60
40
119.4
</pre><pre name="code" class="cpp">#include <cstdio> #include <iostream> #include <algorithm> #include <vector> #include <cstring> #include <queue> #include <cmath> #include <string> #include <map> #include<stack> using namespace std; int main (void) { float d,p,q; cin>>d>>p>>q; printf("%.4f",p*d/(p+q)); }题中最后说明
Namely: let's assume that your answer equals a,
and the answer of the jury is b. The checker program will consider your answer correct if
所以结果至少应保留四位小数(因为没有注意,硬是WA了,又去读了好多遍英文题目,白白浪费时间T^T)
B. Rebranding
给定字符串及需要转换的字符(xi,yi),,将字符串中所有xi变为yi,所有yi变为xi,以此类推,输出最终变化后的字符串。
11 6
abacabadaba
a b
b c
a d
e g
f a
b b
cdcbcdcfcdc
</pre><pre name="code" class="cpp">#include <cstdio> #include <iostream> #include <algorithm> #include <vector> #include <cstring> #include <queue> #include <cmath> #include <string> using namespace std; char s[200050]; char c[26+5]; int main (void) { std::ios::sync_with_stdio(false); for(int i=0;i<26;i++) c[i]=i+'a'; int num,p; char ch1,ch2; cin>>num>>p; for(int i=0;i<num;i++) cin>>s[i]; for(int i=0;i<p;i++) { cin>>ch1>>ch2; if(ch1!=ch2) { for(int i=0;i<26;i++)//c中相应元素互换 { if(ch1==c[i]) c[i]=ch2; else if(ch2==c[i]) c[i]=ch1; } } } for(int i=0;i<num;i++) cout<<c[s[i]-'a']; }之前看题第一反应是用map<char ,vector<int> >,为字符串中每一个字符分配一个不定长数组,储存该字符在字符串中的下标。每次根据该字符所对应下标完成两个字符的交换,交换结束还要进行vector的交换。由于水平有限,写出来交上去一直TLE,改了好多次还是在test11的地方TLE。后来换个角度,从字符本身的变换考虑,通过对最初的保存26个字母的字符数组c进行操作,多次互换确定每个字符所对应的最终新字符,并输出最终字符串。又是水题都做不出系列。。。
C. Median Smoothing
输入一串数字(0或1),通过数组保存,第一项和最后一项不变,求出其余每项与前后两个数字的中位数,并保存在新的数组中,继续对新的数组进行同样操作直到数组不再发生改变,即达到稳定状态。若最终达到稳定状态,输出变换的步骤, 若不能,输出-1。
既然数字串由0和1组成,就只有01相邻才会才发生些改变,即010101..01或者101010...10
0开头:奇:00101011->0010111->0001111 偶:001010100->00010100->0001000->0000000
1开头:奇:110101011->111010111->111101111->111111111 偶:11010100->11101000->11110000
可以看出,在01相邻构成的子串,若数字个数为奇,则最终稳定的子串与其第一个数字相同,若为偶,则前一半与第一个数字相同,后一半与最后的数字相同。
即 对于01相邻构成的子串,直接取半,前一半与第一个数字相同,后一半与最后一个数字相同。
观察可得步数为(数字子串个数-1)/2,总步数取最大值。
4
0 0 1 1
0
0 0 1 1
5
0 1 0 1 0
2
0 0 0 0 0
</pre><pre name="code" class="cpp">#include <cstdio> #include <iostream> #include <algorithm> #include <vector> #include <cstring> #include <queue> #include <cmath> #include <string> #include <map> #include<stack> using namespace std; int n[500050]; int a[500050]; int main (void) { std::ios::sync_with_stdio(false); int num; cin>>num; int end,begin=0,step=0; for(int i=0;i<num;i++) cin>>n[i]; while(begin<num) { end=num-1; a[begin]=n[begin]; for(int i=begin;i<num-1;i++) { if(n[i]==n[i+1]) { end=i; break; } } step=max((end-begin)/2,step);//获取最大步数 for(int j=0;j<(end-begin)/2+1;j++) { a[begin+j]=n[begin]; a[end-j]=n[end]; } begin=end+1; } cout<<step<<endl; cout<<a[0]; for(int i=1;i<num;i++) cout<<" "<<a[i]; }最初在while里面加了一个循环语句,以找到01串的始点,结果不幸TLE,优化好久也没想到是这里的问题,其实不用这个循环同样可以获得正确01串,并且总体上减少了时间消耗:)
先写三道。
A long way to go....这次真要努力了!