USACO2020DEC B

P1

Farmer John 的奶牛正在 “mooZ” 视频会议平台上举行每日集会。她们发明了一个简单的数字游戏,为会议增添一些乐趣。
Elsie 有三个正整数 A、B 和 C(A≤B≤C)。这些数字是保密的,她不会直接透露给她的姐妹 Bessie。她告诉 Bessie 七个范围在 1…109 之间的整数(不一定各不相同),并宣称这是 A、B、C、A+B、B+C、C+A 和 A+B+C 的某种排列。

给定这七个整数,请帮助 Bessie 求出 A、B 和 C。可以证明,答案是唯一的。

//sol 1
//思路是用DFS吧所有可能算出来,然后一个位置一个位置的判断是否满足
//时间复杂度O(7^7)
#include <bits/stdc++.h>
using namespace std;
int p[8];
int ans[8],vis[8],flag = 0;
bool check(){
    if (ans[4] == (ans[1]+ans[2]) && ans[5] == (ans[2]+ans[3]) && ans[6] == (ans[1]+ans[3]) && ans[7] == (ans[1]+ans[2]+ans[3])) return true;
    return false;
}
void DFS(int step){
    if (flag == 1) return;
    if (step > 7){
        if (check()){
            for (int i = 1; i <= 3; i++){
                if (i == 3) cout << ans[i];
                else cout << ans[i] << " ";          //前三位是a,b,c;
            }
            flag = 1;
        }
        return;
    }
    for (int i = 1; i <= 7; i++){
        if (vis[i] == 0){
            vis[i] = 1;
            ans[step] = p[i];
            DFS(step+1);
            vis[i] = 0;
        }
    }
}
int main(){
    for (int i = 1; i <= 7; i++){
        cin >> p[i];
    }
    sort(p+1,p+8);
    DFS(1);
    return 0;
}

//第二种做法
//通过观察发现,对于从小到大排好序的序列来说,一共有两种可能
//一,A+B > C
//二,A+B < C
//所以只需要判断一下第三个位置是否是第一个和第二个位置的和,如果是,则第四位是c,反之第三位是c
#include <bits/stdc++.h>
using namespace std;
int nums[8];
int main(){
    for (int i = 1; i <= 7; i++){
        cin >> nums[i];
    }
    sort(nums+1, nums+8);
    if (nums[1]+nums[2] == nums[3]){
        cout << nums[1] << " " << nums[2] << " " << nums[4];
    }else{
        cout << nums[1] << " " << nums[2] << " " << nums[3];
    }
    return 0;
}

P2

每天,作为她绕农场行走的一部分,奶牛 Bessie 会经过她最喜爱的草地,其中种有 N 朵花(五颜六色的雏菊),编号为 1…N(1≤N≤100),排列成一行。花 i 有 pi 朵花瓣(1≤pi≤1000)。
作为一名崭露头角的摄影家,Bessie 决定给这些花拍些照片。具体地说,对于每一对满足 1≤i≤j≤N 的花 (i,j),Bessie 会给从花 i 到花 j 之间的所有花(包括 i 和 j)拍一张照。
后来 Bessie 查看这些照片时注意到有些照片里存在「平均」的花——一朵恰好有 P 朵花瓣的花,其中 P 等于照片中所有花的花瓣数量的平均值。
Bessie 的照片中有几张存在平均的花?

//这题最简单的暴力枚举即可,优化可以加一个前缀和
#include <bits/stdc++.h>
using namespace std;
int n,ans = 0;
double p[105],sum[105],AVG;
int main(){
    cin >> n;
    for (int i = 1; i <= n; i++){
        cin >> p[i];
        sum[i] = sum[i-1] + p[i];
    }
    for(int i = 1; i <= n; i++){
        for (int j = i+1; j <= n; j++){
            AVG = (sum[j] - sum[i-1])/(double)(j-i+1);
            for (int k = i; k <= j; k++){
                if (p[k] == AVG){
                    ans++;
                    break;
                }
            }
        }
    }
    cout << n+ans << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值