1.数位和
#include<iostream>
using namespace std;
int main(){
char c;
int ans=0;
while(cin.get(c)){
if(c=='\n') break;
ans+=c-'0';
}
cout<<ans;
}
2.消除游戏
#include<iostream>
using namespace std;
//思路:对于每一个棋子,判断其是否可以被消掉,将要被消除的点进行标记,待遍历完毕后记为0
// 如何判断? 找到该棋子左右上下的边界即可,判断边界大小是否大于等于3
#define N 40
struct node{
int c,v;
}a[N][N];
int n,m;
bool could_del(int x,int y){
int u,d,r,l;
for(u=x;u>=0&&a[u][y].c==a[x][y].c;u--);
for(d=x;d<n&&a[d][y].c==a[x][y].c;d++);
for(r=y;r<m&&a[x][r].c==a[x][y].c;r++);
for(l=y;l>=0&&a[x][l].c==a[x][y].c;l--);
return d-u>=4||r-l>=4;
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>a[i][j].c,a[i][j].v=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
{
if(could_del(i,j)) cout<<0<<" ";
else cout<<a[i][j].c<<" ";
}
cout<<endl;
}
}
3.画图
直接模拟就可以:但是这个题有两个坑
- 数学坐标系写代码太麻烦了
-如果之前的字符是’+‘的话,那么经过画线过后不应该被覆盖为’-‘或者’|’,不然只能拿90分
#include<iostream>
#include<algorithm>
using namespace std;
#define N 110
char a[N][N];
int n,m,q;
void _line(int x1,int y1,int x2,int y2){
if(x1==x2){
int ymax=max(y1,y2);
int ymin=min(y1,y2);
for(int i=ymin;i<=ymax;i++){
if(a[x1][i]=='-'||a[x1][i]=='+') a[x1][i]='+';
else a[x1][i]='|';
}
}else{
int xmax=max(x1,x2);
int xmin=min(x1,x2);
for(int i=xmin;i<=xmax;i++){
if(a[i][y1]=='|'||a[i][y1]=='+') a[i][y1]='+';
else a[i][y1]='-';
}
}
}
int dir[][2]={0,1,0,-1,1,0,-1,0};
void _fill(int x,int y,char c){
if(a[x][y]==c) return ;
a[x][y]=c;
for(int i=0;i<4;i++){
int nx=x+dir[i][0];
int ny=y+dir[i][1];
if(nx<0||nx>=m||ny<0||ny>=n) continue;
if(a[nx][ny]=='|'||a[nx][ny]=='-'||a[nx][ny]=='+') continue;
_fill(nx,ny,c);
}
}
int main(){
cin>>m>>n>>q;
_fill(0,0,'.');
while(q--){
int o;
cin>>o;
if(o){
int x,y;
char c;
cin>>x>>y>>c;
_fill(x,y,c);
}else{
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
_line(x1,y1,x2,y2);
}
}
for(int j=n-1;j>=0;j--){
for(int i=0;i<m;i++)
putchar(a[i][j]);
putchar('\n');
}
}
4.送货:
自己的代码:
#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
#define N 10010
//统计奇点个数,若1不是奇点,则无解,若奇点个数不为2也无解
//dfs求解即可
set<int> G[N];
int n,m;
vector<int> res;
void dfs(int k){ //当前的位置在k
if(!G[k].size()) return ;
int nxt=*G[k].begin();
res.push_back(nxt);
G[k].erase(nxt);
G[nxt].erase(k);
dfs(nxt);
}
int main(){
cin>>n>>m;
int k=m;
while(m--){
int a,b;
cin>>a>>b;
G[a].insert(b);
G[b].insert(a);
}
if(G[1].size()%2==0) {
cout<<"-1";
return 0;
}
int cnt=0;
for(int i=1;i<=n;i++)
cnt+=(G[i].size()%2);
if(cnt!=2&&cnt!=0){ //若没有奇点,则回路为从A出发,从A结束
cout<<"-1";
return 0;
}
dfs(1);
if(res.size()!=k) {
cout<<"-1";
return 0;
}
cout<<1<<" ";
for(int i=0;i<res.size();i++)
cout<<res[i]<<" ";
}
错的,只有10分,分析为什么错了:
- 在判断奇点个数时候出错了:
正确的判断代码应该是:
if(cnt!=2&&cnt!=0||(cnt==2&&G[1].size()%2!=1)){
cout<<"-1";
return 0;
}
-
是因为没有用并查集判断连通性吗?
不是,如果图是联通的,那么进行dfs后得到的vector大小一定和m相同 -
正解,dfs函数出错,在遍历时候每次都只取该点的一条边,若该点是奇点就出错了
正确的dfs代码如下: (至于为什么要回溯再记录,我也不清楚)
void dfs(int k){ //当前的位置在k
while(G[k].size()){
int t=*G[k].begin();
G[k].erase(t);
G[t].erase(k);
dfs(t);
}
res.push_back(k);
}
y总完整代码如下:
#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
#define N 10010
//统计奇点个数,若1不是奇点,则无解,若奇点个数不为2也无解
//dfs求解即可
set<int> G[N];
int n,m;
vector<int> res;
void dfs(int k){ //当前的位置在k
while(G[k].size()){
int t=*G[k].begin();
G[k].erase(t);
G[t].erase(k);
dfs(t);
}
res.push_back(k);
}
int main(){
cin>>n>>m;
int k=m;
while(m--){
int a,b;
cin>>a>>b;
G[a].insert(b);
G[b].insert(a);
}
int cnt=0;
for(int i=1;i<=n;i++)
cnt+=(G[i].size()%2);
if(cnt!=2&&cnt!=0||(cnt==2&&G[1].size()%2!=1)){
cout<<"-1";
return 0;
}
dfs(1);
if(res.size()!=k+1) {
cout<<"-1";
return 0;
}
//记得要倒着输出,因为答案也是倒着记录的
for(int i=res.size()-1;i>=0;i--)
cout<<res[i]<<" ";
}
5.第五题不会