赛前听说这次比赛挺水(学校自己说的- -能是真的吗),区域赛铜牌水平,于是本蒟蒻慕名而去,最终果然被大牛血洗。。。
https://www.nowcoder.com/acm/contest/90#question
不过收获还是有一些的,所以特意总结一下:
刚开始比赛,按顺序做题,有点儿紧张,大脑一片空白觉得A题这种水题居然有点儿难做。。。A题递归,头次提交TLE了,TLE表明咱代码还是能得出正确结果的,于是改代码n = 1跑到30输出结果以","间隔。
开一个新代码把输出结果作为const数组,直接输出。第一个AC。。。
前一次代码:
#include <iostream>
using namespace std;
int n;
long long ans;
void f(int x){
if(x == n){
ans++;
return;
}
for(int i = 1;x+i <= n;i++)
f(x+i);
}
int main(){
for(n = 1;n <= 30;n++){
ans = 0;
f(0);
cout << ans << ",";
}
return 0;
}
第二次代码:
#include <iostream>
using namespace std;
const long long a[] = {0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912};
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
cout << a[n] << endl;
}
return 0;
}
刷新看AC%,发现I签到题,ACx2
之后打开D,J,L三道题都看了看,初看觉得J动态规划,暂时放下看L,一看L我应该会吧。。。于是按照约分的思路做……卡了1个多小时,样例都得不出正确结果。。好吧,打 码能力太弱了。
D的话倒是好说一下,经典的LPS算法,求最长回文子串长度n,总长度-n得结果。。ACx3
打开F,发现是poj2917原题,只是输出格式改了改。。ACx4
此时会看J,发现1和n-1是互补的,对n-1个数+1和对1个数-1起到的效果是相同的。。步数step解决了,最大数采用相同思想,对1 2 3这三个数,对3执行-1操作2次,对2进行-1一次。结果为4……意思就是,改动除了最大数的数,则结果的最大数+1
举例
①1 2 4
2-1 = 1
4-1 = 3
step = 1 + 3 = 4
max = 4 + 1 = 5
②1 3 4
3-1 = 2
4-1 = 3
step = 2 + 3 = 5
max = 4 + 2 = 6
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int num[100010];
int main(){
int t,n;
cin >> t;
while(t--){
cin >> n;
int max,min,step = 0;
memset(num,0,sizeof(num));
for(int i = 0;i < n;i++)cin >> num[i];
sort(num,num+n);
max = num[n-1];
min = num[0];
for(int i = 0;i < n;i++)step += num[i]-min;
cout << step << " " << step+min << endl;
}
return 0;
}
ACx5
开K题,一看,应该不难,跟天梯赛里的L1题差不多(参见 古风排版)
代码:
#include <iostream>
#include <cstring>
using namespace std;
string l[100010];
int main(){
int k,t;
cin >> k;
while(k--){
for(int i = 0;i < 100010;i++)l[i].clear();
int n;
cin >> n;
string str;
cin >> str;
if(n == 1){
cout << str << endl;
continue;
}
for(int i = 0;str[i];i++){
t = i%(2*n-2);
if(t >= n)
l[2*n-2-t]+=str[i];
else l[t]+=str[i];
}
for(int i = 0;i < n;i++)cout << l[i];
cout << endl;
}
return 0;
}
值得一提的是这题我WA了两次,没有考虑特殊情况n=1,后来n=1的时候忘了输出换行符- -耽误了十多分钟。。
ACx6
放不下L题,那道耽误了一个多小时的题,这次想想从别的角度试试呢?不用约分的思路。。。我想到数学上的求对数log
比较x^a和y^b,只需比较alogx和blogy
那么这个题就好说了。。。由于不能直接比较浮点数,引入eps。。。因为调整eps的大小(一次1e-5,一次1e-9)又WA了两次,不过能AC已经不错了。。。
代码:
#include <iostream>
#include <cmath>
using namespace std;
const double eps = 1e-3;
int main(){
int t,x,a,y,b;
double m,n;
cin >> t;
while(t--){
cin >> x >> a >> y >> b;
m = log(x);
n = log(y);
if(abs(a*m-b*n) < eps)cout << "Yes\n";
else cout << "No\n";
}
return 0;
}
ACx7
这时候剩下大概一个小时,看AC%决定开G
打开一看便有思路,无非是有点儿变化的行列互换。自信满满写好代码运行样例答案相符,心想运气可真好,还能做一题,可是交上去WA了。。。之后开始了漫长的半个多小时的找错。。。找到几处可能导致WA的地方提交上去都不对,我连WA了5次。。这时候离比赛结束只有不到十分钟了,突然发现对负数的处理上存在问题,向右旋转的次数x为负的时候我直接使x+4,以为这样就成了正值。。。那一屋!改成了if(x<0)x = 4-x%4;之后就AC了,总算没有辜负最后一个小时。。
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
char str[40][40];
char tmp[40][40];
void turn_right(int n,int m){
memset(tmp,0,sizeof(tmp));
memmove(tmp,str,sizeof(str));
memset(str,0,sizeof(str));
char ch;
for(int i = 0;i < n;i++)
for(int j = 0;j < m;j++){
ch = tmp[i][j];
if(ch == '-')ch = '|';
else if(ch == '|')ch = '-';
str[j][n-1-i] = ch;
}
}
int main(){
int t,n,m;
cin >> t;
while(t--){
int x = 0;
cin >> n >> m;
for(int i = 0;i < n;i++)cin >> str[i];
string cmd;
cin >> cmd;
for(int i = 0;cmd[i];i++)
if(cmd[i] == 'R')x++;
else x--;
if(x<0)x = 4-abs(x)%4;
x%=4;
for(int i = 0;i < x;i++){
turn_right(n,m);
swap(n,m);
}
cout << n << " " << m << endl;
for(int i = 0;i < n;i++){
for(int j = 0;j < m;j++)
cout << str[i][j];
cout << endl;
}
cout << endl;
}
return 0;
}
ACx8
8AC对于我这种蒟蒻来说已经不少了,虽然有些遗憾,没有尝试别的题,甚至看都没能看一眼,不过进步总是一步一步地嘛,这次8题,争取下次9题,再下次10题……希望自己能在ACM的路上走远……