yuanshen77

导航

 

                                                         关于STL中二分函数的用法

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e7+5;
ll w[N];
ll n,k;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>k;
    for(int i = 1 ;i <= n ; i++)
        cin>>w[i];
    int pos1 = lower_bound(w+1,w+1+n,k)-w;  //大于等于
    int pos2 = upper_bound(w+1,w+1+n,k)-w;  //大于
    cout<<pos1<<" "<<w[pos1]<<"\n";
    cout<<pos2<<" "<<w[pos2]<<"\n";
    sort(w+1,w+1+n,greater<ll>());  //逆排序
    int pos3 = lower_bound(w+1,w+1+n,k,greater<ll>())-w; //小于等于
    int pos4 = upper_bound(w+1,w+1+n,k,greater<ll>())-w; //小于
    cout<<pos3<<" "<<w[pos3]<<"\n";
    cout<<pos4<<" "<<w[pos4]<<"\n";
    return 0;
}

                                                                                                          Problem - B - Codeforces

   

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n;
ll a[1010][1010];
ll f[1010];
int main() {
    int t ;
    cin >> t;
    while(t--) {
        cin >> n;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++) {
                  cin>>a[i][j];
            }
        for(int i = 1 ; i <= 1010 ; i++)
            f[i] = pow(2,30)-1;   //2^30次方二进制全是1
        for(int i = 1; i <= n ; i++)
            for(int j = 1 ; j <= n ; j++)
            {
                if(i != j)
                {
                    f[i] = (f[i] & a[i][j]);  //根据给的数组a,判断哪些位上必须是1,两个相同,做最坏情况
                }
            }
        int flag = 1 ;
        for(int i = 1 ; i <= n ; i++)
        {
            for(int j = 1 ; j <= n ; j++)
            {
                if(i!=j)
                {
                    if(a[i][j] != (f[i]|f[j]))  //最坏情况都不能满足,说明无法解决
                        flag = 0;
                }
                if(flag==0)
                    break;
            }
            if(flag == 0)
                break;
        }
        if(flag) {
            cout << "Yes" << "\n";
            for(int i = 1; i <= n ; i++)
                cout<<f[i]<<" ";
                cout<<"\n";
        }
        else
            cout<<"No"<<"\n";
    }
    return 0;
}

总结:位运算,根据两个数按位或的结果,可以反推理想情况,就是两个数相同,它们在二进制下结果值有1他们就有1,所以可以用二进制位全是1的2^30-1去和结果做一个按位与从而看结果哪些位为1

 

 

                                Problem - C - Codeforces

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+5;
ll f[N];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    ll t ;
    cin >> t;
    while(t--)
    {
        ll n;
        cin >> n;
        for(int i = 1 ; i <= n ; i++)
            cin>>f[i];
        ll ans = 0;
        ll tmp = 0;
        for(int i = n ; i >= 1; i--) //反向比较
        {
             tmp+=f[i];
             if(i == 1 || tmp > 0)
                 ans+=tmp;
        }
        cout<<ans<<"\n";
 
    }
    return 0;
}

总结:本题是根据权重分配相关的题目,越往后面权重划分越重,所以我们必须从后往前看,一旦后面的后缀和大于0就立马分组,再用一个tmp去累加,就不用考虑乘数如何去取的问题了。

                                      Problem - C - Codeforces

 

posted on 2024-01-20 18:25  江木匠  阅读(13)  评论(0)    收藏  举报