A:三英战吕布
题目描述
输入
输出
- 思维题
- 求出点算距离就行
#include<bits/stdc++.h>
using namespace std;
#define ll long long
double a[5],b[5];
int main(){
for(int i=1;i<=4;i++)
scanf("%lf%lf",&a[i],&b[i]);
double x=(a[1]+a[2]+a[3])/3.0;
double y=(b[1]+b[2]+b[3])/3.0;
printf("%.2f\n",sqrt((a[4]-x)*(a[4]-x)+(b[4]-y)*(b[4]-y)));
return 0;
}
B: a碟求最大值
题目描述
输入
输出
- 求最大值则 i * j 要尽可能大,可以从后往前枚举 i * j ,然后当枚举到 i * j 已经小于找到的最大值时,就可以跳出循环,节省时间
- 注意一个细节,如果定义i 和 j 是int类型的话,i * j 要强制类型转换,不然会丢失精度
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
int a[100005];
int n,k;
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
ll ans=-INF;
for(int i=n-1;i>=1;--i){
if((ll)i*n<=ans)break;//现在i*j已经小于找到的最大值,再往前枚举也只能比现在更小
for(int j=n;j>i;--j){
ll d=(ll)i*j-(ll)k*(a[i]|a[j]);//强转
ans=max(ans,d);
}
}
printf("%lld\n",ans);
}
return 0;
}
C: 超级小分队
题目描述
输入
输出
- 数组b保存前n项和,枚举找出最大的m个数之和就行,比较水
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
int a[1005],b[1005];
int n,m;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=b[i-1]+a[i];
}
int ans=0;
for(int i=m;i<=n;i++){
ans=max(ans,b[i]-b[i-m]);
}
printf("%.2f\n",1.0*ans/m);
return 0;
}
D: X星人的宝藏
题目描述
输入
输出
- 动态规划
- dp[ i ][ j ]表示到第 i 个点时气球已经启动 j 次
- dp[ i ][ j ]该状态可由 i 之前的且距离小于等于m的某个位置 l 转移过来
- 状态转移方程 dp[ i ][ j ]=max(dp[ i ][ j ],dp[ l ][ j-1 ]+b[ i ]);
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int n,m,k;
int ans;
int a[105],b[105];
int dp[105][105];
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i],&b[i]);
memset(dp,-0x3f,sizeof(dp));
dp[1][0]=b[1];
for(int i=2;i<=n;i++)
for(int j=1;j<=k;j++){
for(int l=i-1;l>=1;l--){
if(m>=a[i]-a[l]){
dp[i][j]=max(dp[i][j],dp[l][j-1]+b[i]);
}
else break;
}
ans=max(ans,dp[i][j]);
}
printf("%d\n",ans);
return 0;
}
E: 神奇的口袋
题目描述
输入
输出
- 动态规划水题
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
int a[50];
int dp[50];
int n;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
dp[0]=1;
for(int i=1;i<=n;i++)
for(int j=40;j>=a[i];j--)
dp[j]+=dp[j-a[i]];
printf("%d\n",dp[40]);
return 0;
}
F: 找出直系亲属
题目描述
输入
输出
- 方法1:直接模拟,map记录每一对父母关系,例如mp[a]=b 则a的儿子是b,然后对询问找出所有的可能模拟就行
- 方法2:搜索,就不用找出所有可能,直接搜索,最终搜到了就是有关系,然后根据要求输出就行
- 这题的字符不要单个字符单个字符输入,直接字符串输入一行会节省很多时间
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
int n,m;
map<char,char>mp;
void ask(char a,char b){
if(!mp[a]&&!mp[b]){
puts("-");
}
else if(mp[a]==b){
puts("parent");
}
else if(mp[b]==a){
puts("child");
}
else if(mp[mp[a]]==b){
puts("grandparent");
}
else if(mp[mp[b]]==a){
puts("grandchild");
}
else {
int ans=0;
char c=a;
while(mp[c]&&mp[c]!=b){
c=mp[c];
ans++;
}
if(mp[c]==b){
while(ans>=2){
ans--;
printf("great-");
}
puts("grandparent");
return ;
}
ans=0;
c=b;
while(mp[c]&&mp[c]!=a){
c=mp[c];
ans++;
}
if(mp[c]==a){
while(ans>=2){
ans--;
printf("great-");
}
puts("grandchild");
return ;
}
puts("-");
}
}
int dfs(int be,int la,int ans){
if(be==la)return ans;
if(isalpha(mp[be])) return dfs(mp[be],la,ans+1);
return -1;
}
int main(){
char s[5];
while(~scanf("%d%d",&n,&m)){
mp.clear();
while(n--){
scanf("%s",s);
if(s[1]!='-')mp[s[1]]=s[0];
if(s[2]!='-')mp[s[2]]=s[0];
}
while(m--){
scanf("%s",s);
//ask(s[0],s[1]);//直接模拟
int ans=dfs(s[1],s[0],0);//搜索
if(ans!=-1){
for(int i=3;i<=ans;++i) printf("great-");
if(ans>=2) printf("grand");
puts("child");
continue;
}
ans=dfs(s[0],s[1],0);
if(ans!=-1){
for(int i=3;i<=ans;++i) printf("great-");
if(ans>=2) printf("grand");
puts("parent");
continue;
}
puts("-");
}
}
return 0;
}
G: 最小长方形
题目描述
输入
输出
- 水题
- 左下角坐标(最小的x,最小的y),右上角坐标(最大的x,最大的y)
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
int a,b,c,d;
int x,y;
int main(){
while(scanf("%d%d",&a,&b)&&(a+b)){
c=a;
d=b;
while(scanf("%d%d",&x,&y)&&(x+y)){
a=min(a,x);
b=min(b,y);
c=max(c,x);
d=max(d,y);
}
printf("%d %d %d %d\n",a,b,c,d);
}
return 0;
}
H: 逆序五进制
题目描述
输入
输出
- 水题
#include<bits/stdc++.h>
using namespace std;
int n,m;
void turn(){
string s="";
while(m){
s+=to_string(m%5);
m/=5;
}
reverse(s.begin(),s.end());
cout<<s<<endl;
}
int main(){
cin>>n;
while(n){
m=m*10+n%10;
n/=10;
}
turn();
return 0;
}
I: XP的魔塔
题目描述
输入
输出
- 搜索
- 就是普通的搜索,没什么难度…
- 下面给出dfs和bfs两种方法
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
int n;
bool flag;
int di[][2]={0,1,1,0,0,-1,-1,0};
int vis[105][105];
char a[105][105];
int b[105][105];
int dx,dy;
bool check(int x,int y){
if(x>=1&&x<=n&&y>=1&&y<=n&&a[x][y]!='X')
return 1;
return 0;
}
void dfs(int x,int y,int ans){
if(a[x][y]=='T'||flag){
flag=1;
return ;
}
for(int i=0;i<4;i++){
int xx=x+di[i][0];
int yy=y+di[i][1];
if(check(xx,yy)&&!vis[xx][yy]&&ans>b[xx][yy]){
vis[xx][yy]=1;
dfs(xx,yy,ans-b[xx][yy]);
}
}
}
struct node{
int x,y;
int ans;
bool operator<(const node &q)const{
return ans<q.ans;
}
};
void bfs(){
priority_queue<node>q;
q.push({dx,dy,b[dx][dy]});
while(!q.empty()){
node k=q.top();
q.pop();
if(a[k.x][k.y]=='T'){
flag=1;
return ;
}
vis[k.x][k.y]=1;
for(int i=0;i<4;i++){
int xx=k.x+di[i][0];
int yy=k.y+di[i][1];
if(check(xx,yy)&&k.ans>b[xx][yy]&&!vis[xx][yy]){
q.push({xx,yy,k.ans-b[xx][yy]});
}
}
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
memset(vis,0,sizeof(vis));
flag=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",a[i]+1);
for(int j=1;j<=n;j++)
if(a[i][j]=='S'){
dx=i;
dy=j;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&b[i][j]);
dfs(dx,dy,b[dx][dy]);
//bfs();
if(flag)puts("YES");
else puts("NO");
}
return 0;
}