当ccf撞上cccc,外加前有硬件课设,后有英语竞赛,就很难受,不过,不慌不忙,稳中求进,才是王道
来一套2015年12月的题,2minA题,20minB题,30minC题,留下3h强攻最后两题,然后由于好久没高强度训练了,注意了不免有点不集中,最终400分草草结束
201512-1 数位之和
思路:水题,分解整数,计算各位之和,秒杀级别,千万不能耽误任何时间
#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;
int main()
{
int n;
scanf("%d",&n);
int sum = 0;
while(n)
{
sum += n%10;
n /= 10;
}
printf("%d\n",sum);
return 0;
}
201512-2 消除类游戏
思路:这题由于矩阵给的很小,于是最有效的方法就是做个最暴力的模拟暴搜
#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 = 40;
int chess[maxn][maxn];
bool rechess[maxn][maxn];
int n,m;
void reduce(int x,int y)
{
if(x+3<=n)
{
if(chess[x][y]==chess[x+1][y]&&chess[x][y]==chess[x+2][y])
{
int pos = x+3;
while(pos<n&&chess[x][y]==chess[pos][y])
{
pos++;
}
for(int i=x;i<pos;i++)
{
rechess[i][y] = true;
}
}
}
if(y+3<=m)
{
if(chess[x][y]==chess[x][y+1]&&chess[x][y]==chess[x][y+2])
{
int pos = y+3;
while(pos<m&&chess[x][y]==chess[x][pos])
{
pos++;
}
for(int i=y;i<pos;i++)
{
rechess[x][i] = true;
}
}
}
return ;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(rechess,false,sizeof(rechess));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%d",&chess[i][j]);
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
reduce(i,j);
}
}
for(int i=0;i<n;i++)
{
if(rechess[i][0])
{
printf("%d",0);
}
else
{
printf("%d",chess[i][0]);
}
for(int j=1;j<m;j++)
{
if(rechess[i][j])
{
printf(" %d",0);
}
else
{
printf(" %d",chess[i][j]);
}
}
printf("\n");
}
}
return 0;
}
201512-3 画图
思路:这题完全可以分成两个子操作独立解决,对于画线就是根据原位置信息进行模拟,填充则是做一个dfs
#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 = 110;
char paint[maxn][maxn];
int d[4][2] = { { 0, 1},
{ 0,-1},
{ 1, 0},
{-1, 0} };
int m,n;
void drawline(int x1,int y1,int x2,int y2)
{
if(x1==x2)
{
if(y1>y2)
{
int temp = y1;
y1 = y2;
y2 = temp;
}
for(int i=y1;i<=y2;i++)
{
if(paint[x1][i] == '+')
{
continue;
}
if(paint[x1][i] == '-')
{
paint[x1][i] = '+';
}
else
{
paint[x1][i] = '|';
}
}
}
else
{
if(x1>x2)
{
int temp = x1;
x1 = x2;
x2 = temp;
}
for(int i=x1;i<=x2;i++)
{
if(paint[i][y1] == '+')
{
continue;
}
if(paint[i][y1] == '|')
{
paint[i][y1] = '+';
}
else
{
paint[i][y1] = '-';
}
}
}
return ;
}
void dfsfillblock(int x,int y,char c)
{
if(paint[x][y] == '+' || paint[x][y] == '-' || paint[x][y] == '|' || paint[x][y] == c)
{
return ;
}
paint[x][y] = c;
for(int i=0;i<4;i++)
{
int dx = x + d[i][0];
int dy = y + d[i][1];
if(dx<0||dx>=m||dy<0||dy>=n)
{
continue;
}
dfsfillblock(dx,dy,c);
}
}
int main()
{
int q;
while(cin >> m >> n)
{
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
paint[i][j] = '.';
}
}
cin >> q;
while(q--)
{
int p;
cin >> p;
if(p==0)
{
int x1,x2,y1,y2;
cin >> x1 >> y1 >> x2 >> y2;
drawline(x1,y1,x2,y2);
}
else
{
int x,y;
char c;
cin >> x >> y >> c;
//cout << "***" << c << "***" << endl;
dfsfillblock(x,y,c);
}
}
//cout << n << m << endl;
for(int i=n-1;i>=0;i--)
{
for(int j=0;j<m;j++)
{
cout << paint[j][i];
}
cout << endl;
}
}
return 0;
}
201512-4 送货(50分)
思路:看似一个简单的欧拉路径问题,一开始用链接矩阵暴力一发,由于没考虑到回路靠后原则导致只有20分进账,40分后,确实想不出什么别的问题了,猛然间发现时间已经超过1s了,果断改用优先队列形式邻接链表,并更改了一些小问题后,成功50分进账
#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;
bool con[maxn][maxn];
int num[maxn];
struct cmp
{
bool operator() (const int a,const int b)const
{
return a>b;
}
};
priority_queue<int,vector<int>,cmp> q[maxn];
int main()
{
int n,m;
cin >> n >> m;
memset(con,false,sizeof con);
memset(num,0,sizeof num);
for(int i=1;i<=n;i++)
{
while(!q[i].empty())
{
q[i].pop();
}
}
for(int i=0;i<m;i++)
{
int a,b;
cin >> a >> b;
con[a][b] = true;
con[b][a] = true;
q[a].push(b);
q[b].push(a);
num[a] ++;
num[b] ++;
}
int pos = 1;
vector <int> re;
//cout << m << "#" << endl;
while(m)
{
//cout << m << "#" << endl;
//int ne = 1;
int temp = -1;
//for(;ne<=n;ne++)
//{
while((!q[pos].empty())&&(!con[pos][q[pos].top()]))
{
q[pos].pop();
}
if(q[pos].empty())
{
break;
}
int ne = q[pos].top();
q[pos].pop();
//if(con[pos][ne])
//{
if(num[ne] == 1)
{
temp = ne;
while((!q[pos].empty())&&(!con[pos][q[pos].top()]))
{
q[pos].pop();
}
if(!q[pos].empty())
{
ne = q[pos].top();
q[pos].pop();
q[pos].push(temp);
}
}
//else
//{
re.push_back(ne);
con[pos][ne] = false;
con[ne][pos] = false;
num[ne] --;
num[pos] --;
pos = ne;
//break;
//}
//}
//}
//cout << ne << "*" << m << "*" << endl;
/*if(ne > n)
{
if(temp > 0)
{
re.push_back(temp);
con[pos][temp] = false;
con[temp][pos] = false;
num[temp] --;
num[pos] --;
pos = temp;
}
else
{
break;
}
}*/
m--;
}
if(m>0)
{
cout << "-1" << endl;
}
else
{
cout << 1;
vector <int> :: iterator it = re.begin();
for(;it!=re.end();it++)
{
cout << " " << (*it);
}
cout << endl;
}
return 0;
}
/*错误1:环路*/
/*错误2:细节,变量修改*/
/*错误3:超时,优先队列*/
/*错误4:起点序号*/
/*错误5:一致性,及时去除无效节点*/
201512-5 矩阵(50分)
思路:典型的矩阵快速幂问题,然而O(n^3)的矩阵运算对于稍微大一点的顶点数确实没什么好的方法,时间空间看似都没什么问题,但快速幂处的爆栈真心捉急,最后,水个小数据水50分吧
扫描二维码关注公众号,回复:
8759922 查看本文章
#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 = 50+10;
typedef struct MATRIX
{
int aa[maxn][maxn];
}Matrix;
int m;
Matrix A;
int b[maxn];
Matrix ama(Matrix &p,Matrix &q)//O(n^3)
{
Matrix r;
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
r.aa[i][j] = 0;
for(int z=0;z<m;z++)
{
r.aa[i][j] ^= (p.aa[i][z] & q.aa[z][j]);
}
}
}
return r;
}
Matrix ak(int k)//O(log(k))
{
if(k==1)
{
return A ;
}
else if((k&1)==1)
{
Matrix temp = ak(k-1);
return ama(temp,A);
}
else
{
Matrix temp = ak(k/2);
return ama(temp,temp);
}
}
void cal(Matrix p)
{
int re;
//cout << "#" << m << endl;
for(int i=0;i<m;i++)
{
re = 0;
//cout << re << "**" << endl;
for(int j=0;j<m;j++)
{
re ^= (p.aa[i][j] & b[j]);
}
printf("%d",re);
}
printf("\n");
}
int main()
{
//cout << "*" << endl;
while(scanf("%d",&m)!=EOF)
{
//cout << "*" << m << endl;
//memset(ori,false,sizeof ori);
//oria.clear();
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
scanf("%1d",&A.aa[i][j]);
}
}
for(int i=0;i<m;i++)
{
scanf("%1d",&b[i]);
}
int n;
scanf("%d",&n);
while(n--)
{
int k;
scanf("%d",&k);
if(k==0)
{
for(int i=0;i<m;i++)
{
printf("%d",b[i]);
}
printf("\n");
}
else
{
cal(ak(k));
}
}
}
return 0;
}
/*爆栈*/
稍微定个小小的计划,最近几天一天一套题,估计可能还会剩两道题,但也是没办法的事了,谁让刚开学的时候自己有点浑浑噩噩沉迷吃鸡呢
至于ccf只能抽出零散时间来刷了,而未解决的ccf难题,都放到最后一天晚上吧和第二天上午吧
勿以往之不谏,预祝ccf和cccc都能取得好成绩吧