这次……惨败……只出了2题……而第二题居然在final 的时候判出wa了……
话说这简直坑啊Q^Q 我的--写成了++居然都过了pretest……
#include <cmath>
#include <vector>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a1,a2,a3;
int b1,b2,b3;
int n;
cin>>a1>>a2>>a3>>b1>>b2>>b3>>n;
int c=a1+a2+a3;
int m=b1+b2+b3;
while(c+m)
{
if(c)
{
if(c>=5) c-=5,n--;
else c=0,n--;
}
else
{
if(m)
{
if(m>=10) m-=10,n--;
else m=0,n--;
}
}
if(n<0)
{
puts("NO");
return 0;
}
}
puts("YES");
return 0;
}
A的话没什么好说的,贪心最简单背包即可……
可以通过删除字母来完成转换【automaton】
可以通过改变字母位置来完成转换【array】
两个都得用【both】
都用都转不了【need tree】
所以—— 字符串长度一样且使用了一样数量的每种字母的话:array ,否则nt
字符串长度不同>A包含B子序列:automaton
不包含时若A包含B所有字母及相应数量:both,反之nt
++ 和 -- 的纰漏……叹气……
Code:
#include <cmath>
#include <vector>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int mark[26];
int main()
{
memset(mark,0,sizeof mark);
string s,t;
cin>>s>>t;
if(s.length()==t.length())
{
for(int i=0;i<s.length();i++)
{
mark[s[i]-'a']++;
mark[t[i]-'a']--;
}
int flag=0;
for(int i=0;i<26;i++)
{
if(mark[i]!=0) flag=1;
}
if(flag==0)
{
puts("array");
return 0;
}
else
{
puts("need tree");
return 0;
}
}
else if(s.length()<t.length())
{
puts("need tree");
return 0;
}
else
{
int pos=0,flag=0;
for(int i=0;i<t.length();i++)
{
while(s[pos]!=t[i])
{
pos++;
if(pos>=s.length())
{
flag=1;
break;
}
}
pos++;
if(flag==1)break;
}
if(flag==0)
{
puts("automaton");
return 0;
}
else
{
for(int i=0;i<s.length();i++)
{
mark[s[i]-'a']++;
}
for(int i=0;i<t.length();i++)
{
mark[t[i]-'a']--;
}
for(int i=0;i<26;i++)
{
if(mark[i]<0)
{
puts("need tree");
return 0;
}
}
puts("both");
return 0;
}
}
return 0;
}
C:篱笆按给出数字顺序为高度,每次只能横着刷或者数着刷,问最小刷的次数(贪心DFS)
Bizon the Champion isn't just attentive, he also is very hardworking.
Bizon the Champion decided to paint his old fence his favorite color, orange. The fence is represented as n vertical planks, put in a row. Adjacent planks have no gap between them. The planks are numbered from the left to the right starting from one, the i-th plank has the width of 1 meter and the height of aimeters.
Bizon the Champion bought a brush in the shop, the brush's width is 1 meter. He can make vertical and horizontal strokes with the brush. During a stroke the brush's full surface must touch the fence at all the time (see the samples for the better understanding). What minimum number of strokes should Bizon the Champion do to fully paint the fence? Note that you are allowed to paint the same area of the fence multiple times.
The first line contains integer n (1 ≤ n ≤ 5000) — the number of fence planks. The second line containsn space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 109).
Print a single integer — the minimum number of strokes needed to paint the whole fence.
5 2 2 1 2 1
3
2 2 2
2
1 5
1
In the first sample you need to paint the fence in three strokes with the brush: the first stroke goes on height 1 horizontally along all the planks. The second stroke goes on height 2 horizontally and paints the first and second planks and the third stroke (it can be horizontal and vertical) finishes painting the fourth plank.
In the second sample you can paint the fence with two strokes, either two horizontal or two vertical strokes.
In the third sample there is only one plank that can be painted using a single vertical stroke.
贪心DFSCode:
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
#define N 5005
int a[N];
int n;
int solve(int l,int r){
int ans=r-l+1;
int m=a[l],i,j;
if (l>r) return 0; //stop
for (i=l+1;i<=r;++i) m=min(m,a[i]); //find m=min
for (i=l;i<=r;++i) a[i]-=m; //All decrease m
for (j=l;j<=r;++j) if (a[j]!=0) break; //find first segment's left
for (i=j;i<=r;++i) if (a[i]==0) //find first segment's right
{
m+=solve(j,i-1); //solve it
if (m>ans) return ans;//specially,if reach the end
else j=i+1; //go ahead to next segment
}
if (j<=r) m+=solve(j,r); //reach the r:right
return min(m,ans); //m can not beyond ans
}
int main()
{
int i,j;
cin>>n;
for (i=0;i<n;++i) cin>>a[i];
cout<<solve(0,n-1);
return 0;
}
先贴一个帅瞎不偿命的DP做法 pflueger@Codeforces
Code:
#include <iostream>
using namespace std;
int main() {
int n; cin >> n;
int a[n+1];
a[0] = 0;
for (int i=1; i<=n; i++) cin >> a[i];
int dp[n+1][n+1];
for (int j=0; j<=n; j++) dp[n][j] = 0;
for (int i=n-1; i>=0; i--) for (int j=0; j<=i; j++) {
if (a[j] >= a[i+1]) dp[i][j] = dp[i+1][i+1]; //Already painted
else {
dp[i][j] = min( 1 + dp[i+1][j], a[i+1]-a[j] + dp[i+1][i+1]);
}
}
cout << dp[0][0] << endl;
}
Bizon the Champion isn't just charming, he also is very smart.
While some of us were learning the multiplication table, Bizon the Champion had fun in his own manner. Bizon the Champion painted ann × m multiplication table, where the element on the intersection of the i-th row and j-th column equals i·j (the rows and columns of the table are numbered starting from 1). Then he was asked: what number in the table is the k-th largest number? Bizon the Champion always answered correctly and immediately. Can you repeat his success?
Consider the given multiplication table. If you write out all n·m numbers from the table in the non-decreasing order, then the k-th number you write out is called the k-th largest number.
The single line contains integers n, m and k (1 ≤ n, m ≤ 5·105; 1 ≤ k ≤ n·m).
Print the k-th largest number in a n × m multiplication table.
2 2 2
2
2 3 4
3
1 10 5
5
A 2 × 3 multiplication table looks like this:
1 2 3 2 4 6
D:nXm的矩阵中aij=i*j,问nXm矩阵中第k大的数字是哪个(二分查找)
Code:
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e6 + 6;
ll f(ll x, int n, int m)//f: there are f() less than x in nxm blanks
{
ll res = 0;
--x;
for(int i=1;i<=n;++i) res+=min((ll)m, x/i);
return res;
}
int main(){
ll n,m,k;
cin>>n>>m>>k;
ll l=1, r=1LL*n*m+1, x;
while(l<r) //binary
{
x = (l+r)>>1;
if(f(x,n,m)<k) l=x+1; else r=x;
}
cout<<l-1<<endl;
return 0;
}
E:看到就被吓住,没敢写
Offical Solution:
Solution:7139559
Because rewards of one type can be on one shelf, lets calculate number of cups — a and number of medals — b. Minimum number of shelves that will be required for all cups can be found by formula (a + 5 - 1) / 5. The same with shelves with medals: (b + 10 - 1) / 10. If sum of this two values more than n then answer is "NO" and "YES" otherwise.
Solution:7139584
Consider each case separately. If we use only suffix automaton then s transform to some of its subsequence. Checking that t is a subsequence of s can be performed in different ways. Easiest and fastest — well-known two pointers method. In case of using suffix array we can get every permutation of s. If it is not obvious for you, try to think. Thus, s and t must be anagrams. If we count number of each letter in each string, we can check this. If every letter appears in s the same times as in t then words are anagrams. In case of using both structures strategy is: remove some letters and shuffle the rest. It is possible if every letter appears in s not less times than in t. Otherwise it is impossible to make t from s. Total complexity O(|s| + |t| + 26).
Solution:7139610
To solve this problem we need to understand some little things. First, every horizontally stroke must be as widely as possible. Second, under every horizontally stroke should be only horizontally strokes. So, if bottom of fence painted by horizontally stroke then number of this strokes must at least min(a1, a2, ..., an). These strokes maybe divides fence into some unpainted disconnected parts. For all of these parts we need to sum they answers. Now its clearly that solution is recursive. It takes segment [l, r] and height of painted bottom h. But we must not forget about situation when all planks painted with vertically strokes. In this case answer must be limited by r - l + 1 (length of segment). With given constrains of n we can find minimum on segment by looking all the elements from segment. Complexity in this case will be O(n2). But if we use for example segment tree, we can achieve O(nlogn) complexity.
Solution:7139620
Solution is binary search by answer. We need to find largest x such that amount of numbers from table, least than x, is strictly less than k. To calculate this count we sum counts from rows. In i th row there will be . Total complexity is O(nlog(nm)).
Solution:7139644
Learn how to transform Xi into Xi + 1. For this we need to concatenate lists of divisors for all elements of Xi. To do this efficiently, precalculate divisors of X (because for every i Xi consist of its divisors). It can be done by well-known method with complexity. How to calculate divisors of divisors? Need to know that for the given constrains for X maximum number of divisors D(X)will be 6720 (in the number 963761198400), so divisors of divisors can be calculated in O(D2(X)) time. With this lists we can transform Xi into Xi + 1 in O(N) time, were N = 105 — is the limit of numbers in output. Now learn how to transform Xi into X2i. What says Xi? Besides what would be X after i steps, it can tell where goes everyone divisor of X after i - 1 steps. Actually, Xi is concatenation of all Yi - 1, where Y is divisor of X. For example, 103 = [1, 1, 1, 2, 1, 1, 5, 1, 1, 2, 1, 5, 1, 2, 5, 10] = [1] + [1, 1, 2] + [1, 1, 5] + [1, 1, 2, 1, 5, 1, 2, 5, 10] = 12 + 22 + 52 + 102. How to know which segment corresponds for some Y? Letspos(Y) be the first index of Y in Xi. Then needed segment starts from pos(prev(Y)) + 1 and ends in pos(Y), where prev(Y) is previous divisor before Y in sorted list of divisors. So, to make X2i from Xi we need to know where goes every element from Xi after isteps. We know all its divisors — it is one step, and for every divisor we know where it goes after i - 1 step. Thus, we again need to concatenate some segments in correct order. It also can be done in O(N) time. How to find now Xk for every k? The method is similar as fast exponentiation:
Xk = [X] when k = 0,
if k is odd then transform Xk - 1 to Xk,
if k is even then transform Xk / 2 to Xk.
This method takes O(logk) iterations. And one small trick: obviously that for X > 1 Xk starts from k ones, so k can be limited by N. Total complexity of solution is .