假 题解都是认真瞎几把 写的,看不懂的看代码
A-meeting 题目链接
题意让你求要带多少个毯子,即求有几个暖气片覆盖不到的点。暴力模拟即可。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int x[1000], y[1000], r[1000], a, b, c, d, n, j, k, A = 0;
cin >> a >> b >> c >> d >> n;
for (int i = 0; i < n; ++i)
cin >> x[i] >> y[i] >> r[i];
for (int i = min(a, c); i <= max(a, c); i++)
{
for (j = min(b, d); j <= max(b, d); j++)
{
if (i == a || i == c || j == b || j == d)
{
for (k = n; k--;)
if((i-x[k])*(i-x[k])+(j - y[k]) * (j - y[k]) <= r[k] *r[k])
break;
A += k < 0;//如果K小于0 则表示没有一个暖气片能覆盖到这个点
}
}
}
cout << A;
}
B-Tic-tac-toe题目链接
题意是给你一个井字棋让你判断当前棋的状态是否合法,合法的话有没有人赢,没人人能赢的话下一个谁下
暴力模拟就行 这个模拟 真香
#include<bits/stdc++.h>
using namespace std;
char a[5][5];
int cnt0,cntx;
bool win(char x)
{
if(a[0][0]==x&&a[0][1]==x&&a[0][2]==x)return true;
if(a[1][0]==x&&a[1][1]==x&&a[1][2]==x)return true;
if(a[2][0]==x&&a[2][1]==x&&a[2][2]==x)return true;
if(a[0][0]==x&&a[1][0]==x&&a[2][0]==x)return true;
if(a[0][1]==x&&a[1][1]==x&&a[2][1]==x)return true;
if(a[0][2]==x&&a[1][2]==x&&a[2][2]==x)return true;
if(a[2][0]==x&&a[1][1]==x&&a[0][2]==x)return true;
if(a[0][0]==x&&a[1][1]==x&&a[2][2]==x)return true;
return false;
}
bool judge()
{
if(win('X')&&cntx==cnt0)return true;
if(win('0')&&cntx==cnt0+1)return true;
if(cntx>cnt0+1||cntx<cnt0)return true;
return false;
}
int main()
{
for(int i=0;i<3;i++)
{
scanf("%s",a[i]);
}
cnt0=0,cntx=0;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(a[i][j]=='0')
{
cnt0++;
}
if(a[i][j]=='X')
{
cntx++;
}
}
}
if(judge())
{
printf("illegal\n");
}
else if(win('0'))
{
printf("the second player won\n");
}
else if(win('X'))
{
printf("the first player won\n");
}
else if(cnt0+cntx==9)
{
printf("draw\n");
}
else if(cnt0==cntx)
{
printf("first\n");
}
else
{
printf("second\n");
}
return 0;
}
C-Spreadsheets题目链接
题意:题目给出了EXCEL行和列的两种表示方法,输入后判断是哪一种表示方法并把它转化成另一种
按题意模拟即可 字符和数字的转化可看成类似转化成26进制
#include<bits/stdc++.h>
using namespace std;
string s;
bool pd()
{
for(int i=2;i<s.size();i++)
{
if(s[i]=='C')return true;
}
return false;
}
int main()
{
string ans;
int n,l,r;
cin>>n;
while(n--)
{
cin>>s;
if(s[0]=='R' && s[1]>='0' &&s[1]<='9' && pd())
{
int i;
r=l=0;
for(i=1;s[i]!='C';i++)
{
l*=10;
l+=s[i]-'0';
}
for(i=i+1;i<s.size();i++)
{
r*=10;
r+=s[i]-'0';
}
ans="";
while(r)
{
int tmp=r%26;
char c=(tmp+'A'-1);
if(tmp==0)c='Z',r-=26;
ans+=c;
r/=26;
}
for(int i=ans.size()-1;i>=0;i--)
{
cout<<ans[i];
}
cout<<l<<endl;
}
else
{
ans="";
int i=0;
l=r=0;
for(i=0;s[i]>='A'&&s[i]<='Z';i++)
{
ans+=s[i];
}
for(i;i<s.size();i++)
{
r*=10;
r+=s[i]-'0';
}
int tmp=1;
for(i=ans.size()-1;i>=0;i--)
{
l+=tmp*(ans[i]-'A'+1);
tmp*=26;
}
cout<<'R'<<r<<'C'<<l<<endl;
}
}
return 0;
}
D-Escape 题目链接
题目大意:公主要从龙洞跑路公主以每小时vp英里的速度奔跑,而龙则以每小时vd英里的速度飞行。龙会在t小时后发现逃跑的路,并会立刻追上公主。一旦龙抓住了公主,她就会扔下一个东西来分散龙的注意力。在这种情况下,他会停下来,拿起物品,回到洞穴,花上f个小时来整理库房里的东西。只有在这之后,他才会重新开始追逐。问要几个东西才能保证公主不会被抓回去。
模拟一下就是小学生的解方程题 要注意的是龙和公主同时到达城堡时不算龙抓住公主,
#include<bits/stdc++.h>
using namespace std;
int main()
{
double vd,vp,c,t,f;
int ans=0;
cin>>vp>>vd>>t>>f>>c;
if(vp>=vd)
{
cout<<0<<endl;
return 0;
}
double l=vp*t; //l表示公主逃跑距离 v表示龙与公主速度差
double real_l=l+l*1.0/(vd-vp)*vp;
while(real_l<c)
{
ans++;
double ti=f+real_l*1.0/vd;
l=real_l+vp*ti;
real_l=l+l*1.0/(vd-vp)*vp;
}
cout<<ans<<endl;
return 0;
}
E-Dijkstra题目链接
题目大意:看题目标题就是了,要记录一下路径
输入好像有1e5个点 边也只有1e5 果断spfa
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
typedef long long int ll;
int head[maxn],pre[maxn],vis[maxn];
ll dis[maxn];
const ll inf=0x3f3f3f3f3f;
struct node
{
int to,l,next;
}e[maxn*2];
int cnt,n,m;
void add(int x,int y,int l)
{
e[cnt].to=y;
e[cnt].next=head[x];
e[cnt].l=l;
head[x]=cnt++;
}
int dij(int s)
{
queue<int> q;
for(int i=0;i<=n;i++)
{
vis[i]=0;
dis[i]=inf;
}
dis[s]=0;
vis[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
if(dis[v]>dis[u]+e[i].l)
{
pre[v]=u;
dis[v]=dis[u]+e[i].l;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
if(dis[n]==inf)return -1;
return dis[n];
}
int main()
{
cin>>n>>m;
int x,y,l;
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++)
{
cin>>x>>y>>l;
add(x,y,l);
add(y,x,l);
}
int ans=dij(1);
if(ans==-1)cout<<-1<<endl;
else
{
stack<int> q;
int v=n;
while(v!=1)
{
q.push(v);
v=pre[v];
}
cout<<1;
while(!q.empty())
{
cout<<" "<<q.top();
q.pop();
}
}
return 0;
}
F-The least round way题目链接
题目大意:给一个NN的矩阵,让你从1-1位置走到n-n每次只能向下或向右走,让你找一条路径使得路径上的点相乘后末尾的0的数量最少
考虑到末尾会出现0的情况大致可以分成三种,1.乘数中有一个0,这样的话最后结果就是0,2.乘数中有5和偶数,偶数和5相乘尾数会有0,3.乘数中有10的倍数.
每一个25会增加一个0 所以考虑把每一个位置上的数可以整除2几次和整除5几次记录下来,末尾0的个数就是2和5个数中小的那一个。然后把矩阵分别按2的个数和5的个数记忆化搜索一下,答案就是dp到n-n这个位置上2和5个数小的那一个。再倒推路径输出。需要特判一种情况就是有0,且正常求出时的答案大于1的时候。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+10;
int dp[maxn][maxn][3];
char mp[maxn][maxn][2];
int n,x,f=-1;
void print(int k)
{
cout<<endl;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cout<<dp[i][j][k]<<" ";
}
cout<<endl;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&x);
if(x==0)f=i;
else{
while(x%2==0 && x)x/=2,dp[i][j][0]++;
while(x%5==0 && x)x/=5,dp[i][j][1]++;}
}
}
for(int i=2;i<=n;i++)
{
dp[1][i][0]+=dp[1][i-1][0];
dp[1][i][1]+=dp[1][i-1][1];
dp[i][1][0]+=dp[i-1][1][0];
dp[i][1][1]+=dp[i-1][1][1];
}
for(int i=2;i<=n;i++)
{
for(int j=2;j<=n;j++)
{
dp[i][j][0]+=min(dp[i-1][j][0],dp[i][j-1][0]);
dp[i][j][1]+=min(dp[i-1][j][1],dp[i][j-1][1]);
}
}
int k=0;
if(dp[n][n][1]<dp[n][n][0])k=1;
if(f!=-1 && dp[n][n][k]>1)
{
cout<<1<<endl;
for(int i=1;i<f;i++)cout<<'D';
for(int i=1;i<n;i++)cout<<'R';
for(int i=f;i<n;i++)cout<<'D';
return 0;
}
printf("%d\n",dp[n][n][k]);
int mx=n,my=n;
string ans="";
while(1)
{
if(mx==1)
{
for(;my>1;my--)ans+='R';
break;
}
if(my==1)
{
for(;mx>1;mx--)ans+='D';
break;
}
if(dp[mx-1][my][k]<dp[mx][my-1][k]){ans+='D';mx--;}
else{ans+='R';my--;}
}
for(int i=ans.size()-1;i>=0;i--)
{
cout<<ans[i];
}
return 0;
}
G-Lorry题目链接
题目大意:有N个小船,每个小船的体积为1或2,每个小船有不同的载重。现有一载重为V的卡车,问卡车能拉走的小船的载重和的方案
考虑到数据范围,加上小船每个体积只有1和2,用贪心。先把体积为2的小船全部装上车,再考虑体积为1的小船能不能装上车或者替换掉车上的船
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct node
{
int p,id;
}yi[maxn],er[maxn];
bool vis[maxn];
bool cnm(node a,node b)
{
return a.p>b.p;
}
int main()
{
int n,m,ans=0,x,y,z,cnt=0,tot=0,xx=0,yy=0;
queue<int> s;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>x>>y;
yy+=y;
xx+=x;
if(x==1)
{
yi[++cnt].p=y;
yi[cnt].id=i;
}
else
{
er[++tot].p=y;
er[tot].id=i;
}
}
if(xx<=m)
{
cout<<yy<<endl;
for(int i=1;i<=n;i++)cout<<i<<" ";
return 0;
}
sort(er+1,er+tot+1,cnm);
sort(yi+1,yi+cnt+1,cnm);
int i=1,j=1;
while(m>1 && j<=tot)
{
ans+=er[j].p;
vis[er[j].id]=1;
m-=2;
j++;
}
j--;
while(m>0 && i<=cnt)
{
m--;
ans+=yi[i].p;
vis[yi[i].id]=1;
i++;
}
while(j>0 && i<=cnt)
{
if((yi[i].p+yi[i+1].p-er[j].p)>0)
{
ans+=(yi[i].p+yi[i+1].p-er[j].p);
vis[yi[i].id]=vis[yi[i+1].id]=1;
vis[er[j].id]=0;
i+=2;
j--;
}
else break;
}
cout<<ans<<endl;
for(int i=1;i<=n;i++)
{
if(vis[i])cout<<i<<" ";
}
return 0;
}
H-Roads in Berland题目链接
题目大意:小镇上原来有每个城市之间的最短路径,现在考虑要修K条路,需要你来算修完这条路后每对城市之间的最短路和。
暴力枚举每对城市再加入这条路后的最短路有没有变化,具体实现看代码,每次加边后都要暴力一次。(反正数据小,暴它丫的)
#include<bits/stdc++.h>
using namespace std;
const int maxn=310;
int mp[maxn][maxn];
int main()
{
int n,m,x,y,l;
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)cin>>mp[i][j];
}
cin>>m;
for(int k=1;k<=m;k++)
{
cin>>x>>y>>l;
mp[x][y]=mp[y][x]=min(l,mp[x][y]);
for(int i=1;i<=n;i++)//暴力枚举
{
for(int j=1;j<=n;j++)
{
mp[i][j]=mp[j][i]=min(mp[i][j],mp[i][x]+mp[x][y]+mp[y][j]);
}
}
long long int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)ans+=mp[i][j];
}
cout<<ans<<endl;
}
return 0;
}