Atcoder 173题解(A~E)

A
失误WA了两次耻辱!!!
AC代码:

#include
#include
#include 
#include
#include
#include
#include
#include
#include
#include
#include 
#define ll long long
using namespace std;

int main()
{
    int n;
    cin>>n;
    if(n%1000==0)
    {
        cout<<0<<endl;
    }
    else
    {
        int k=n%1000;
        int c=1000-k;
        cout<<c<<endl;


    }
    return 0;
}

B
简单统计一下
模拟即可
AC代码:

#include
#include
#include 
#include
#include
#include
#include
#include
#include
#include
#include 
#define ll long long
using namespace std;
string a="AC";
string b="WA";
string c="TLE";
string d="RE";
int x[5];
int main()
{
    string k;
    int n;
    cin>>n;
    for(int i=0; i<n; i++)
    {
        cin>>k;
        if(k==a)
        {
            x[1]++;
        }
        else if(k==b)
        {
            x[2]++;
        }
        else if(k==c)
        {
            x[3]++;
        }
        else if(k==d)
        {
            x[4]++;
        }
    }
    cout<<a<<" x "<<x[1]<<endl;
    cout<<b<<" x "<<x[2]<<endl;
    cout<<c<<" x "<<x[3]<<endl;
    cout<<d<<" x "<<x[4]<<endl;
    return 0;
}

C
二进制枚举套娃,套两层即可
AC代码:

#include
#include
#include 
#include
#include
#include
#include
#include
#include
#include
#include 
#define ll long long
using namespace std;
char maps[7][7];
int sum;
int ans;
int a[7];//纪录每行的总和
int b[7];//纪录每列的总和

int main()
{
    int n,m,k;
    cin>>n>>m>>k;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            cin>>maps[i][j];
            if(maps[i][j]=='#')
            {
                sum++;
                a[i]++;
                b[j]++;
            }
        }
    }
    //if(sum==k)
    //{
       // ans++;
  //  }
    for(int i = 0; i < (1<<n); i++)//行枚举
    {
        for(int x = 0; x < (1<<m); x++)//列枚举
        {
            int t=sum;
            for(int j = 0; j < n; j++)//减去行的
            {

                if(i & (1 << j))
                {
                    t=t-a[j];
                }
            }
            for(int y = 0; y < m; y++)//减去列的
            {
                if(x & (1 << y))
                {
                    t=t-b[y];
                }
            }
            for(int j = 0; j < n; j++)
            {
                for(int y = 0; y < m; y++)
                {
                    if(i & (1 << j)&&x & (1 << y))//加上反复减去的
                    {
                        if(maps[j][y]=='#')
                        {
                            t++;
                        }
                    }
                }
            }
            if(t==k)
            {
                //cout<
                ans++;
            }

        }
    }
    cout<<ans<<endl;
    return 0;
}

D
从大到小最大的数只能贡献一次友好值,其余均可以共享两次,贪心即可。
AC代码:

#include
#include
#include 
#include
#include
#include
#include
#include
#include
#include
#include 
#define ll long long
using namespace std;
int a[200010];
ll sum;
int main()
{
    int n;
    cin>>n;
    for(int i=0; i<n; i++)
    {
        cin>>a[i];
    }
    sort(a,a+n);
    if(n>1)
    {
        sum+=a[n-1];
    }
    int k=n-2;
    n=n-2;
    while(n>=2)
    {
        sum=sum+2*a[k--];
        n=n-2;

    }
    if(n==1)
    {
        sum+=a[k];
    }
    cout<<sum<<endl;
    return 0;
}

E
N个数取K个数的积最大,分为四种情况
第一种:全是正数,则取最大的K个数的积
第二种:没有正数,则取最大的K个数的积
第三种:有正有负,按照绝对值排列,对最大的K个的值进行判断,如果值为正,则直接输出,如果为负则判断前N-K个数中最大的正数于后K个数中的最小负数交换,将前N-K个数中最大的负数于后K个数中最小的正数交换,比较大小即可
AC代码:

#include 
#include 
#include 
#include 

using namespace std;

long long  n, k;
long long ans = 1;
long long  l_neg = -1,l_pos = -1, r_neg = -1, r_pos = -1;
//l_neg表示前N-K项最大的负数,l_pos表示前N-K项最大的正数,r_neg表示后K项最小负数,r-pos表示后K项最小正数
const long long int M = 1000000007;

bool cmp(long long int a,long long  int b)//按照绝对值排序
{
    return abs(a) < abs(b);
}

long long int calc(vector<long long int> a)
{
    long long temp = 1;
    for(long long int i = n - k; i < n; i++)
        temp = (temp * a[i]) % M;
    return (temp+M)%M;
}
int main()
{
    cin >> n >> k;
    vector<long long int> a(n, 0);
    for(long long int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    sort(a.begin(), a.end(), cmp);
    for(long long int i = n - k; i < n; i++)
    {
        ans = (ans * a[i]) % M;//计算后K项的积
        if(r_pos == -1 && a[i] > 0)//找出后K项中最小的正数
            r_pos = i;
        if(r_neg == -1 && a[i] < 0)//找出后K项中最小的负数
            r_neg = i;
    }
    for(long long int i = n - k - 1; i >= 0; i--)
    {
        if(l_pos == -1 && a[i] > 0)//找出前N-K项中最大的正数
            l_pos = i;
        if(l_neg == -1 && a[i] < 0)//找出前N-K项中最大的负数
            l_neg = i;
    }

    if(ans < 0 && n != k)
    {
        if(r_pos == -1)//如果后K项没有正数
        {
            if(l_pos == -1)//如果前N-K项也没有正数
            {
                ans = 1;
                for(long long int i = 0; i < k; i++)
                    ans = (ans * a[i]) % M;
            }
            else
            {
                swap(a[l_pos], a[r_neg]);
                ans = calc(a);
            }
        }
        else
        {
            if(l_neg == -1)
            {
                swap(a[l_pos], a[r_neg]);
                ans = calc(a);
            }
            else if(l_pos == -1)
            {
                swap(a[l_neg], a[r_pos]);
                ans = calc(a);
            }
            else
            {
                vector<long long int> c1 = a;
                vector<long long int> c2 = a;
                swap(c1[l_neg], c1[r_pos]);
                swap(c2[l_pos], c2[r_neg]);
                ans=(abs(a[l_neg]*a[r_neg])>abs(a[l_pos]*a[r_pos]))?calc(c1):calc(c2);//判断交换之后哪一个比较大
            }
        }
    }
    cout << (ans+M)%M << endl;
    return 0;
}

你可能感兴趣的:(Atcoder)