A
题意:给出n个不同的整数,问第二大的整数是第几个整数。
思路:结构体排序
#include <stdio.h>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
#include <list>
#include <cstdlib>
#include <set>
#include <queue>
#define PI pair<int,int>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
typedef long long ll;
const int maxx=2e5+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n;
struct node
{
int num,s;
}a[maxx];
bool cmp(node a,node b)
{
return a.s<b.s;
}
void solve()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
a[i].num=i;
scanf("%d",&a[i].s);
}
sort(a+1,a+n+1,cmp);
printf("%d",a[n-1].num);
}
int main()
{
int _t=1;
//scanf("%d",&_t);
while(_t--)
{
solve();
}
system("pause");
}
E
题意:给定一张图,n个点,n-1条边,优先遍历与当前点相连中编号最小的点,没有点可以允许返回。求遍历所有点的顺序。
思路:对每个点可以到达的点进行排序,回溯时记得输出。
#include <stdio.h>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
#include <list>
#include <cstdlib>
#include <set>
#include <queue>
#define PI pair<int,int>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
typedef long long ll;
const int maxx=2e5+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n;
vector<int>v[maxx];
bool vis[maxx];
void dfs(int x)
{
vis[x]=1;//标记走过
printf("%d ",x);//第一次走到时
for(int i=0;i<v[x].size();i++)//遍历该点可到达的点
{
int nex=v[x][i];
if(!vis[nex])
{
vis[nex]=1;
dfs(nex);
printf("%d ",x);//回溯也要走一遍
}
}
}
void solve()
{
scanf("%d",&n);
for(int i=1;i<=n-1;i++)
{
int a,b;
scanf("%d %d",&a,&b);
v[a].push_back(b);//a可以到达的点
v[b].push_back(a);//b可以到达的点
}
for(int i=1;i<=n;i++)//对每个点可到达的点进行排序
{
sort(v[i].begin(),v[i].end());
}
dfs(1);
}
int main()
{
int _t=1;
//scanf("%d",&_t);
while(_t--)
{
solve();
}
system("pause");
}
F
题意:给你n种货币,m种货币之间的汇率关系。让你判断这些货币通过这些汇率关系能不能增值。
思路:因为给的是货币名称,我们可以先用map将货币关系转化成一幅图,然后用佛洛依德算法。
#include <stdio.h>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
#include <list>
#include <cstdlib>
#include <set>
#include <queue>
#define PI pair<int,int>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
typedef long long ll;
const int maxx=2010;
const int inf=0x3f3f3f3f;
using namespace std;
int n,m,t;
map<string,int>q;
double mp[35][35];
void solve()
{
while(~scanf("%d",&n)&&n)
{
for(int i=1;i<=n;i++)
{
string s;
cin>>s;
q[s]=i;
mp[i][i]=1;
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
string from,to;
double w;
cin>>from>>w>>to;
mp[q[from]][q[to]]=w;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=1;k<=n;k++)
{
mp[j][k]=max(mp[j][k],mp[j][i]*mp[i][k]);//汇率关系 : j -> k = j -> i * i -> k
}
}
}
int flag=0;
for(int i=1;i<=n;i++)
{
if(mp[i][i]>1) //最后看i->i是否大于1
{
flag=1;
break;
}
}
printf("Case %d: %s\n",++t,flag? "Yes":"No");
}
}
int main()
{
int _t=1;
//scanf("%d",&_t);
while(_t--)
{
solve();
}
system("pause");
}
G
题意:给定h*w的矩阵,其中n张牌写有数字,给出这n张牌的坐标。若一行或一列中没有带数字的牌就删掉这一行或这一列,执行完所有操作后,这些带数字牌的坐标是多少。
思路:答案是带有数字的卡牌的相对坐标,并且我们只关注行列是否有带数字的牌,不关注卡牌的数量。所有我们可以离散化所有带数字卡牌的坐标,二分查找卡片的相对坐标即为答案。
#include <stdio.h>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
#include <list>
#include <cstdlib>
#include <set>
#include <queue>
#define PI pair<int,int>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
typedef long long ll;
const int maxx=1e9+10;
const int inf=0x3f3f3f3f;
using namespace std;
struct node
{
int x,y;
}a[100010];
vector<int>vx,vy;
int h,w,n;
int get(int x,vector<int> &v)
{
return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
void solve()
{
scanf("%d %d %d",&h,&w,&n);
for(int i=1;i<=n;i++)
{
scanf("%d %d",&a[i].x,&a[i].y);
vx.push_back(a[i].x);
vy.push_back(a[i].y);
}
sort(vx.begin(),vx.end());
sort(vy.begin(),vy.end());
vx.erase(unique(vx.begin(),vx.end()),vx.end());
vy.erase(unique(vy.begin(),vy.end()),vy.end());
for(int i=1;i<=n;i++)
{
printf("%d %d\n",get(a[i].x,vx),get(a[i].y,vy));
}
}
int main()
{
int _t=1;
//scanf("%d",&_t);
while(_t--)
{
solve();
}
system("pause");
}
I
#include <stdio.h>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
#include <list>
#include <cstdlib>
#include <set>
#include <queue>
#define PI pair<int,int>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
typedef long long ll;
const int maxx=510;
const int inf=0x3f3f3f3f;
using namespace std;
int h,w;
char mp[maxx][maxx];
int cost[maxx][maxx];
int dir[4][2]={{0,-1},{0,1},{-1,0},{1,0}};
struct P
{
int x,y;
};
deque<P>q;
bool check(int x,int y)
{
if(x<=0||x>h||y<=0||y>w) return false;
return true;
}
void bfs(int sx,int sy)
{
memset(cost,0x3f,sizeof(cost));
cost[1][1]=0;
q.push_front({sx,sy});
while(!q.empty())
{
P now=q.front();q.pop_front();
for(int i=0;i<4;i++)
{
int nx=now.x+dir[i][0];
int ny=now.y+dir[i][1];
if(!check(nx,ny)) continue;
if(mp[nx][ny]=='.')
{
if(cost[nx][ny]>cost[now.x][now.y])
{
cost[nx][ny]=cost[now.x][now.y];
q.push_front({nx,ny});
}
}
else
{
for(int j=-1;j<=1;j++)
{
for(int k=-1;k<=1;k++)
{
int dx=nx+j;
int dy=ny+k;
if(!check(dx,dy)) continue;
if(cost[dx][dy]>cost[now.x][now.y]+1)
{
cost[dx][dy]=cost[now.x][now.y]+1;
q.push_back({dx,dy});
}
}
}
}
}
}
}
void solve()
{
scanf("%d %d",&h,&w);
for(int i=1;i<=h;i++)
{
for(int j=1;j<=w;j++)
{
cin>>mp[i][j];
}
}
bfs(1,1);
printf("%d\n",cost[h][w]);
}
int main()
{
int _t=1;
//scanf("%d",&_t);
while(_t--)
{
solve();
}
system("pause");
}
J
题意:给定n座山的高度hi,当>=时,难度会增加。问如何安排这些山使得第一座山和最后一座山的高度差尽可能小的同时难度最大。
思路:首先要使两侧山的高度差最小,需要找出两座高度最接近的两座山和放在两侧。然后要使难度最大,所以排序后山高度要最多的递增。即
#include <stdio.h>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
#include <list>
#include <cstdlib>
#include <set>
#include <queue>
#define PI pair<int,int>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
typedef long long ll;
const int maxx=2e5+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n;
ll a[maxx];
ll c[maxx];
void solve()
{
scanf("%d",&n);
int mi=inf,ii=-1;
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
sort(a+1,a+n+1);
for(int i=2;i<=n;i++)
{
c[i]=a[i]-a[i-1];
if(c[i]<mi)
{
mi=c[i];
ii=i;
}
}
printf("%lld ",a[ii-1]);
for(int i=ii+1;i<=n;i++) printf("%lld ",a[i]);
for(int i=1;i<ii-1;i++) printf("%lld ",a[i]);
printf("%lld ",a[ii]);
printf("\n");
}
int main()
{
int _t=1;
scanf("%d",&_t);
while(_t--)
{
solve();
}
system("pause");
}
L
题意:A和B玩游戏,开始时正整数n,每轮可以让当前数减去一个因子(除1和当前数外的因子),最后无法进行操作的玩家输掉,A先手,问谁会取胜。
思路:①当n为奇数时,A只能减去一个奇数因子D,设n=r*D,B得到的n-D一定是一个偶数且含有奇数因子,因为(r-1)*D!=,(r-1)*D一定含有奇数因子。此时B减去奇数因子返回奇数给对手,A只能再减去奇数因子返回带有奇数因子的偶数给B。所以A总是拿到奇数,又因为质数总是奇数,所以输的是A。(但特例2也是质数,但B拿到的是含有奇数因子的偶数,所以不存在这种情况。)
②当n为偶数且含有奇数因子时,同上,A胜。
③当n为偶数且没有奇数因子时,即n=,A只能减去,B得到仍为偶数,,若为奇数,A就输了。所以A只能让k1 = k - 1,B同理。所以每次让n减为原来的一半,只需考虑k的奇偶即可:当k为奇数时,最后A拿到2,B胜;当k为偶数时,最后B拿到2,A胜。
#include <stdio.h>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
#include <list>
#include <cstdlib>
#include <set>
#include <queue>
#define PI pair<int,int>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
typedef long long ll;
const int maxx=1e9+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n;
void solve()
{
scanf("%d",&n);
if(n&1) cout<<"Bob\n";
else
{
int num=0;
while(n%2==0)
{
num++;
n/=2;
}
if(n!=1) cout<<"Alice\n";
else
{
if(num&1) cout<<"Bob\n";
else cout<<"Alice\n";
}
}
}
int main()
{
int _t=1;
scanf("%d",&_t);
while(_t--)
{
solve();
}
system("pause");
}