A-PUBG
题意:从出发位置到目标位置遇到的敌人数量最少。
BFS+优先队列(板子题。。。wa两发忘了memset了)
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
const int N = 101;
int n,a[N][N],px,py,dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
bool vis[N][N];
struct node{
int x,y,cost;
friend bool operator < (node n1,node n2){
return n1.cost > n2.cost;
}
};
int bfs(int x,int y)
{
priority_queue<node> q;
node cur,nxt;
cur.x = x,cur.y = y, cur.cost = 0;
q.push(cur);
while(!q.empty())
{
cur = q.top();
q.pop();
if(cur.x == px&&cur.y == py)
return cur.cost;
for(int i = 0; i < 4; ++i){
nxt.x = cur.x + dir[i][0];
nxt.y = cur.y + dir[i][1];
if(nxt.x<0||nxt.y>=n||nxt.x>=n||nxt.y<0||vis[nxt.x][nxt.y] == true)
continue;
vis[nxt.x][nxt.y] = true;
nxt.cost = cur.cost + a[nxt.x][nxt.y];
// printf("%d\n",a[nxt.x][nxt.y]);
q.push(nxt);
}
}
return -1;
}
int main() {
// freopen("in.txt","r",stdin);
while(~scanf("%d",&n))
{
int tx,ty;
memset(a,0, sizeof(a));
memset(vis,0, sizeof(vis));
for(int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
scanf("%d", &a[i][j]);
if (a[i][j] == -1)
tx = i, ty = j,vis[i][j] = true;
if (a[i][j] == -2)
px = i, py = j;
}
}
int ans = bfs(tx,ty);
printf("%d\n",ans+2);
}
return 0;
}
B-precise math function
题意:求n的π次方
签到题。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
int main()
{
int t,n,x;
cin>>t;
while(t--)
{
cin>>n>>x;
printf("%.*f\n",x,pow(n,acos(-1)));
}
}
C-颜料的混合
咳咳,恕蒻不会(挠头
D-打篮球
题意:三个人两两打篮球,给出每一轮的胜者序列,问是否满足。
按题意模拟即可,当时蒻蒻很气的写出了所有情况,代码很冗长,就给大家看一个好看一些的吧~
#include <bits/stdc++.h>
using namespace std;
int main ()
{
int n,op;
while (cin >> n) {
int vis[10] = {0};
vis[1] = 1;
vis[2] = 1;
bool flag = true;
for (int i = 0;i < n;++i) {
cin >> op;
if (!vis[op]) {
flag = false;
}
for (int j = 1;j <= 3;++j) {
if (j != op) {
if (vis[j] == 1) vis[j] = 0;
else if (vis[j] == 0) vis[j] = 1;
}
}
}
if (flag) puts("YES");
else printf("NO\n");
}
return 0;
}
E-233
题意:两数相乘。
java大数,Python,c++高精度皆可,这里蒻用的java大数。
import java.util.Scanner;
import java.math.BigInteger;
public class Main {
public static void main(String[]args){
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for(int i = 0 ; i < t; ++i){
BigInteger x1 = in.nextBigInteger();
BigInteger x2 = in.nextBigInteger();
System.out.println(x1.multiply(x2));
}
in.close();
}
}
F-扫雷
很迷的一题。。。
题意:先给出n×m地图,然后k次点击,(给出x,y坐标),如果点到雷就直接输出在第几步死的,然后结束,否则输出最后一步后的地图情况。
蒻的解法是如果点到的是点点,那么就按照扫雷的规则,将那一块联通块全都涂成0,如果碰到雷就记住第几步即可。(记住千万不要就此结束比如break或者return 0了,后面可能还有数据)最后如果没踩雷就输出地图即可。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
const int N = 501;
char a[N][N];
bool vis[N][N];
int nxt[8][2] = {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}},n,m;
void dfs(int x,int y)
{
a[x][y] = '0';
vis[x][y] = true;
for(int i = 0; i < 8; ++i){
int tx = x + nxt[i][0];
int ty = y + nxt[i][1];
if(a[tx][ty]=='*'||tx<0||tx>=n||ty<0||ty>=m||vis[tx][ty]==true) continue;
dfs(tx,ty);
}
}
int main() {
// freopen("in.txt","r",stdin);
int t,k;
cin>>t;
while(t--){
memset(vis,0, sizeof(vis));
scanf("%d%d%d",&n,&m,&k);
for(int i = 0; i < n; ++i){
for(int j = 0; j < m; ++j){
scanf(" %c",&a[i][j]);
}
}
int x,y,ans = -1;
for(int i = 0; i < k; ++i){
scanf("%d%d",&x,&y);
if(a[x-1][y-1]=='*'&&ans==-1){
ans = i+1;
}
if(a[x-1][y-1]=='.') dfs(x-1,y-1);
vis[x-1][y-1] = true;
}
if(ans==-1) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (vis[i][j])
printf("%c", a[i][j]);
else
printf("%c", '.');
}
puts("");
}
}else{
printf("Game over in step %d\n",ans);
}
}
return 0;
}
但是,令蒻想不到的是,居然又是蒻想多了,根本不需要涂联通块,直接将点到的点点变成0就行了。
29行代码!!(心累)
#include <iostream>
#include <cstdio>
using namespace std;
int n,m,k,t;
char a[501][501];
int main()
{
cin>>t;
while(t--){
cin>>n>>m>>k;
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j)
scanf(" %c",&a[i][j]);
int x,y,ans = -1;
for(int i = 0; i < k; ++i){
cin>>x>>y;
x--,y--;
if(a[x][y]=='*'&&ans==-1) ans = i+1;
if(a[x][y]=='.') a[x][y] = '0';
}
if(ans==-1){
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j)
putchar(a[i][j]);
puts("");
}else{
printf("Game over in step %d\n",ans);
}
}
return 0;
}
G-火车上的2连座
题意:一排4座,中间隔开,求不被隔开的2连座(优先前排的,如果前排多解,优先左排),将其涂为’+’。
所以按题意模拟即可。。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
const int N = 1001;
int n;
char a[N][N];
int main() {
// freopen("in.txt","r",stdin);
while(~scanf("%d",&n))
{
int flag = 0;
for(int i = 0; i < n; ++i){
for(int j = 0; j < 5; ++j){
scanf(" %c",&a[i][j]);
}
if(flag==0&&a[i][0]==a[i][1]&&a[i][1]=='O'){
flag = 1;
a[i][0] = a[i][1] = '+';
}
if(flag==0&&a[i][3]==a[i][4]&&a[i][3]=='O'){
flag = 1;
a[i][3] = a[i][4] = '+';
}
}
if(flag){
puts("YES");
for(int i = 0; i < n; ++i){
for(int j = 0; j < 5; ++j)
printf("%c",a[i][j]);
putchar('\n');
}
}else{
puts("NO");
}
}
return 0;
}
H-程序员的好印象
这道题如果读懂题,其实也是签到题。。
题意:求最长上升子序列(但记住是大于等于),比如0 0 1 0 1 1 0 1,答案是0 0 1 1 1 1(长度为6)
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
const int N = 1001;
int n,a[101];
int inf = 0x3f;
int dp[101];
int main() {
// freopen("in.txt","r",stdin);
while(~scanf("%d",&n))
{
for(int i = 0; i < n; ++i){
scanf("%d",&a[i]);
}
memset(dp,inf, sizeof(dp));
for(int i = 0; i < n; ++i){
*upper_bound(dp,dp+n,a[i]) = a[i];
}
int cnt = upper_bound(dp,dp+n,inf) - dp;
printf("%d\n",cnt);
}
return 0;
}
I题和J题就不不补~(≧▽≦)/~啦啦啦