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