ACM CF005 总结

ACM CF005 总结

A - Maximum Increase CodeForces - 702A 

    简单dp题,求最长连续上升子序列长度

#include<bits/stdc++.h>
using namespace std;
int a[100005], dp[100005] = {0};
int main()
{
    std::ios::sync_with_stdio(0);
	int n, i, j, k;
	cin >> n;
	for(i = 1; i <= n; i++)cin >> a[i];
	dp[1] = 1;
	for(i = 2; i <= n; i++)
    {
        dp[i] = 1;
        if(a[i] > a[i - 1])dp[i] = max(dp[i], dp[i - 1] + 1);
    }
    int ans = -1;
    for(i = 1; i <= n; i++)ans = max(ans, dp[i]);
	cout << ans << endl;
	return 0;
}

B - Powers of Two CodeForces - 702B

求任意两个数组合能构成2^x的个数,暴力模拟会超时,当时想到存每个数对应的个数,然后遍历,找2^x - ai的个数加在sum里,但是没实现出来,觉得用map可以做,但是最后还是没打出来,思路还不够清晰,map也不太会用,赛后补上。

TLE:

#include<bits/stdc++.h>
using namespace std;
long long a[100005];
int main()
{
    std::ios::sync_with_stdio(0);
    long long n, i, j, k;
    cin >> n;
    for(i = 1; i <= n; i++)cin >> a[i];
    long long sum = 0;
    for(i = 1; i <= n; i++)
    {
        for(j = i + 1; j <= n; j++)
        {
            long long qwe = 1;
            long long asd = a[i] + a[j];
            while(qwe < asd)qwe *= 2;
            if(qwe == asd)sum++;
        }
    }
    cout << sum << endl;
    return 0;
}

使用set减少循环TLE(其实并没有优化):

#include<bits/stdc++.h>
using namespace std;
long long a[100005];
int main()
{
    set<long long>s;
    long long z = 1, minn = 1000000001, maxn = -1;
    std::ios::sync_with_stdio(0);
    long long n, i, j, k;
    cin >> n;
    for(i = 1; i <= n; i++)
    {
        //scanf("%lld", &a[i]);
        //minn = min(minn, a[i]);
        cin >> a[i];
        maxn = max(maxn, a[i]);
    }
    maxn *= 2;
    while(z <= maxn){z*=2; s.insert(z);}
    long long sum = 0;
    for(i = 1; i <= n; i++)
    {
        for(j = i + 1; j <= n; j++)
        {
            //long long qwe = 1;
            long long asd = a[i] + a[j];
            if(s.count(asd) == 1)sum++;
            //if(qwe == asd)sum++;
        }
    }
    cout << sum << endl;
    return 0;
}

cin 和 scanf, cout 和 printf不能混合使用(WA)

#include<bits/stdc++.h>
using namespace std;
long long a[100005];
int main()
{
    set<long long>s;
    long long z = 1, minn = 1000000001, maxn = -1;
    std::ios::sync_with_stdio(0);
    long long n, i, j, k;
    cin >> n;
    for(i = 1; i <= n; i++)
    {
        //scanf("%lld", &a[i]);
        //minn = min(minn, a[i]);
        scanf("%lld", &a[i]);
        
        maxn = max(maxn, a[i]);
    }
    maxn *= 2;
    while(z <= maxn){z*=2; s.insert(z);}
    long long sum = 0;
    for(i = 1; i <= n; i++)
    {
        for(j = i + 1; j <= n; j++)
        {
            //long long qwe = 1;
            long long asd = a[i] + a[j];
            if(s.count(asd) == 1)sum++;
            //if(qwe == asd)sum++;
        }
    }
    cout << sum << endl;
    return 0;
}

使用map减少循环(相当于开了一个1e9的dp数组记录个数)(AC)

#include<bits/stdc++.h>
using namespace std;
int num[100005];
map <int ,int > mp;
int main(){
    int n;
    scanf("%d",&n);
    long long ans = 0;
    for(int  i = 0;i<n;i++){
        int x;
        scanf("%d",&x);
        for(int  i =1;i<32;i++){
            ans+= mp[(1<<i)-x];
        }
        mp[x]++;
    }
    printf("%I64d",ans);
    return 0;
}

另外 i << k 是位运算,相当于把i扩大2^k背,比如1<<4表示16(1*2^4)

因为太困了,所以只看了两题,在之后的比赛中补上。

2018.6.4

猜你喜欢

转载自blog.csdn.net/qq_16530503/article/details/80563778