不知不觉间,大学已经过去了一大半了,acm生涯也随着乌鲁木齐之行的谢幕而逐渐进入了暮年,多么希望自己再年轻一年就好了。
这一年来,平心而论确实可能为了丰富的大学生活而并没有太过于重视训练,涉猎过广,满满的经历导致了精力的分散,不过也算还可以吧,有了不少提升了,本可以有更好成绩的,感觉还是有些地方存在很大空间,但毕竟存在取舍
那么,就让明年的ccf以及cccc,省赛这些谢幕曲不留遗憾,完成未完成的奋斗生涯。
由于之前的ccf刷题记感觉很好,于是决定在之前的基础上推出2.0终极版,以提高自己的能力,继续自己的acm生涯,使自己在接下来的acm生涯末期不留遗憾。
说来也巧,今天正是距我上一次考ccf出成绩刚好一周年的日子,想想去年的自己还无所事事,到处浪荡,做了两题甚至还做睡着了,不过经过一年的时间从弱鸡选手成长为icpc区域赛选手也还算有较大进步的。
刷题ing
ccf的第一套题,感觉难度还是不大的,2h45min成功ak,第一次ak ccf的一整场比赛。以一场ak里程碑来庆祝一周年纪念日,感觉还是蛮不错的
同样是四年前这个时间的老题了,题型感觉和现在完全不一样
201312-1 出现次数最多的数
a题一如既往的水题,瞬间秒切
思路:由于数据范围很小,那么就利用类似于桶排的思想,强行模拟一遍就好了
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 1e4+10;
int s[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(s,0,sizeof s);
while(n--)
{
int temp;
scanf("%d",&temp);
s[temp]++;
}
int maxt = 0;
int id = 0;
for(int i=1;i<=10000;i++)
{
if(s[i]>maxt)
{
maxt = s[i];
id = i;
}
}
printf("%d\n",id);
}
return 0;
}
201312-2 ISBN号码
b题就现在的b题来说,难度还是不大的,依旧是数组字符串处理问题,但是还是在读取上出了点小问题,34min,成功ac,不过这速度就有点慢了
思路:由于取模具有交换性,那么当然还是强行模拟咯。数字字符的读取与处理问题,还是%c,%d,%1d的灵活运用与转换,最后注意一下括号的位置啊,一点点小错误就能debug很长时间的
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 1e5+10;
char isbn[10];
int main()
{
scanf("%c",&isbn[0]);
int sum = isbn[0] - '0';
for(int pos = 1;pos<9;pos++)
{
scanf("%c",&isbn[pos]);
if(isbn[pos] == '-')
{
pos--;
}
else
{
sum = (sum + (int)(isbn[pos]-'0') * (pos+1) )% 11;
}
//cout << isbn[i] << "*" << endl;
}
scanf("%c%c",&isbn[9],&isbn[9]);
//cout << re << "*" << endl;
bool rig = false;
if(sum == 10)
{
if(isbn[9] == 'X')
{
rig = true;
}
else
{
isbn[9] = 'X';
}
}
else
{
if(sum == (int)(isbn[9] - '0'))
{
rig = true;
}
else
{
isbn[9] = sum + '0';
}
}
//cout << "***" << endl;
if(rig)
{
//cout << "*" << endl;
printf("Right\n");
}
else
{
//cout << "**" << endl;
printf("%c-%c%c%c-%c%c%c%c%c-%c\n",isbn[0],isbn[1],isbn[2],isbn[3],isbn[4],isbn[5],isbn[6],isbn[7],isbn[8],isbn[9]);
}
return 0;
}
201312-3 最大的矩形
c题就和原来完全不一样了,当时的这题还是递推dp题,现在已经被经典的大模拟所替代了,递推想明白就比大模拟好写多了,感觉我做这类递推还是比较有心得的,14min成功ac
思路:看了一眼数据范围,支持n方算法,那么当然直接区间暴力,先预处理区间最小值,再枚举区间找最大值就好了,这题很清晰,就喜欢这种题目
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 1e3+10;
int maxh[maxn][maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int h;
int maxa = 0;
for(int i=0;i<n;i++)
{
scanf("%d",&h);
maxh[i][i] = h;
maxa = max(maxa,h);
for(int j=0;j<i;j++)
{
maxh[j][i] = min(maxh[j][i-1],h);
maxa = max(maxa,maxh[j][i] * (i-j+1));
}
}
printf("%d\n",maxa);
}
return 0;
}
201312-4 有趣的数
d题与现在的图论题也完全不一样了,这题倒是个数学题,数学题刚好也是我擅长的,24min ac
思路:这题本想着模拟的,一看取模,那肯定是不行了。
于是又想到打表找规律,以及生产算法的构造,发现似乎也都不怎么行,最终定位为数学题
感觉现在对暴力+一个算法的套路已经有了一定的认识了,记得之前经常卡在这种题上
不难发现,0、1可以归为一类,2、3可以归为一类,而且首元素一定是2,于是只要暴力枚举0、1组元素数量k,对长为n,k个0、1元素的组合共有C(n-1,k)种,最后两组内分别统计,结果相乘即可,最后就是对于组合数的计算,由于直接用公式存在除,对模问题需要求个逆元,比较麻烦,根据数据范围,直接n方递推杨辉三角即可
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 1010;
const long long mod = 1000000007LL;
long long comb[maxn][maxn];
void initial(int n)
{
comb[0][0] = 1;
for(int i=1;i<n;i++)
{
comb[i][0] = 1LL;
//cout << comb[i][0] << " ";
comb[i][i] = 1LL;
for(int j=1;j<i;j++)
{
comb[i][j] = comb[i-1][j-1] + comb[i-1][j] % mod;
//cout << comb[i][j] << " ";
}
//cout << comb[i][i] << endl;
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
initial(n);
long long sum = 0;
for(long long k=2;k<=n-2;k++)
{
sum = (sum + (comb[n-1][k] * (k-1) % mod) * (n-k-1) % mod) % mod;
}
printf("%lld\n",sum);
}
return 0;
}
201312-5 I’m stuck!
e题的图论感觉有点类似现在d题的位置,dfs还是比较明显的,48min完成代码编写,然而感觉不知是自己太久没写代码了,还是自己代码示例太弱了,卡在字母使用上,又过了30min才成功过样例1wa,毫无疑问被卡掉了,最后在进行3min小细节修改以及11min分号查错,终于完成ak大业
e题总用时1h32min,整场总用时2h44min,最后一题用了一大半时间,不过总的结果还是可喜可贺的
思路:明显的dfs,从起点正向暴搜减去从终点逆向暴搜,分成dfs以及可达性判断两部分,思路很明确,但代码实现确实捉急啊,最后,考虑结果特殊情况
1.终点不一定会停止,可能继续前进
2.起点和终点的作用都可以等同为‘+’,四面可通可达
3.stuck条件为被困在起点,而不是无满足条件点
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 55;
char m[maxn][maxn];
bool vis[maxn][maxn];
bool cm[maxn][maxn];
int tcheck[maxn][maxn];
int r,c;
int t = 0;
/*
void prin()
{
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
cout << cm[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
*/
bool movup(int x,int y)
{
if(x<1||x>=r||y<0||y>=c)
return false;
if((m[x][y] == '+') || (m[x][y] == '|') || (m[x][y] == 'S') || (m[x][y] == 'T'))
return true;
else
return false;
}
bool movdown(int x,int y)
{
if(x<0||x>=r-1||y<0||y>=c)
return false;
if((m[x][y] == '+') || (m[x][y] == '|') || (m[x][y] == '.') || (m[x][y] == 'S') || (m[x][y] == 'T'))
return true;
else
return false;
}
bool movlef(int x,int y)
{
if(x<0||x>=r||y<1||y>=c)
return false;
if((m[x][y] == '+') || (m[x][y] == '-') || (m[x][y] == 'S') || (m[x][y] == 'T'))
return true;
else
return false;
}
bool movrig(int x,int y)
{
if(x<0||x>=r||y<0||y>=c-1)
return false;
if((m[x][y] == '+') || (m[x][y] == '-') || (m[x][y] == 'S') || (m[x][y] == 'T'))
return true;
else
return false;
}
void dfs(int x,int y,bool d)
{
//cout << "*" << d << endl;
if(!vis[x][y])
return ;
vis[x][y] = false;
//cout << "*" << endl;
if(d)
{
//cout << m[x][y] << endl;
if(m[x][y] == '#')
{
return ;
}
//cout << "#" << endl;
cm[x][y] = true;
if(movup(x,y))
dfs(x-1,y,d);
if(movdown(x,y))
dfs(x+1,y,d);
if(movlef(x,y))
dfs(x,y-1,d);
if(movrig(x,y))
dfs(x,y+1,d);
return ;
//prin();
}
else
{
//cout << "#*" << endl;
if(m[x][y] == '#')
{
return ;
}
cm[x][y] = false;
//cout << x << " " << y << " " << m[x][y] << t << endl;
//tcheck[x][y] = t++;
//cout << "*#" << endl;
if(movdown(x-1,y))
dfs(x-1,y,d);
if(movup(x+1,y))
dfs(x+1,y,d);
if(movrig(x,y-1))
dfs(x,y-1,d);
if(movlef(x,y+1))
dfs(x,y+1,d);
return ;
}
}
int main()
{
int str,stc,enr,enc;
scanf("%d%d",&r,&c);
memset(cm,false,sizeof(cm));
for(int i=0;i<r;i++)
{
getchar();
for(int j=0;j<c;j++)
{
scanf("%c",&m[i][j]);
//cout << m[r][c] << "+++" << endl;
if(m[i][j] == 'S')
{
str = i;
stc = j;
}
else if(m[i][j] == 'T')
{
enr = i;
enc = j;
}
}
//cout << m[r][0] << "++" << endl;
}
//cout <<m[0][0] << "--" << endl;
//prin();
int sum1 = 0;
memset(vis,true,sizeof(vis));
dfs(str,stc,true);
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
if(cm[i][j])
{
sum1++;
}
}
}
//prin();
memset(vis,true,sizeof(vis));
dfs(enr,enc,false);
//prin();
int sum = 0;
cm[str][stc] = false;
cm[enr][enc] = false;
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
if(cm[i][j])
{
sum++;
}
}
}
if(sum1 == 1)
{
printf("I'm stuck!\n");
}
else
{
printf("%d\n",sum);
}
return 0;
}
文章地址:http://blog.csdn.net/owen_q/article/details/78836466