Educational Codeforces Round 19 A, B, C, E(xjb)
题目链接:http://codeforces.com/contest/797
A题
题意:给出两个数n, k,问能不能将n分解成k个因子相乘的形式,不能输出-1,能则输出其因子;
思路:将n质因分解,若质因子数目对于k则可行,随便将其组合成k个因子即可,反之则不行;
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int MAXN=1e5; 5 int a[MAXN]; 6 7 int main(void){ 8 int n, k, indx=0; 9 cin >> n >> k; 10 for(int i=2; i<=sqrt(n); i++){ 11 while(n%i==0){ 12 a[indx++]=i; 13 n/=i; 14 } 15 } 16 if(n>1) a[indx++]=n; 17 if(indx<k){ 18 cout << -1 << endl; 19 }else{ 20 for(int i=0; i<k-1; i++){ 21 cout << a[i] << " "; 22 } 23 int cnt=1; 24 for(int i=k-1; i<indx; i++){ 25 cnt*=a[i]; 26 } 27 cout << cnt << endl; 28 } 29 return 0; 30 }
B题
题意:给出一个含有n个元素的数组,求其子序列的和最大且为奇数,输出其和;
思路:先求出所有正数的和,若为奇数直接输出即可,不然则再加一个最大的负数并使其为奇数或减去一个最小的奇数;
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int MAXN=1e5+10; 5 int a[MAXN]; 6 7 int main(void){ 8 int n, cnt=MAXN; 9 cin >> n; 10 for(int i=0; i<n; i++){ 11 cin >> a[i]; 12 int gg=abs(a[i]); 13 if((gg&1)&&gg<cnt){ 14 cnt=gg; 15 } 16 } 17 sort(a, a+n); 18 int ans=0, indx=n-1; 19 while(a[indx]>0){ 20 ans+=a[indx]; 21 indx--; 22 } 23 if(ans&1){ 24 cout << ans << endl; 25 }else{ 26 cout << ans-cnt << endl; 27 } 28 return 0; 29 }
C题
题意:给出一个字符串,从第一关字符开始去s中字符放入t数组中,可以从任意时刻从t末尾取字符放入u中,问u可能的最小字典序排列;
思路:显然这个过程就是栈的操作过程,那么只需要用栈模拟一下这题即可;
先预处理一个数组str, str[i]存储从s末尾字符到第i个字符中的最小字符;
再遍历一遍s字符串,对于当前地 i 个字符,维护顶元素>str[i],最终得到的出栈顺序即为答案;
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int MAXN=1e5+10; 5 stack<int> st; 6 int str[MAXN]; 7 8 int main(void){ 9 string s; 10 cin >> s; 11 int len=s.size(); 12 str[len]=30; 13 for(int i=len-1; i>=0; i--){ 14 str[i]=min(str[i+1], s[i]-'a'); 15 } 16 int indx=0; 17 for(int i=0; i<len; i++){ 18 while(!st.empty()){ 19 int cnt=st.top(); 20 if(cnt<=str[i]){ 21 cout << (char)(cnt+'a'); 22 st.pop(); 23 }else break; 24 } 25 st.push(s[i]-'a'); 26 } 27 while(!st.empty()){ 28 int cnt=st.top(); 29 st.pop(); 30 cout << (char)(cnt+'a'); 31 } 32 cout << endl; 33 return 0; 34 }
D题:看懂题目再补。。。
E题
题意:有一个含n个元素的数组,接下来有q个查询,每组给出两个数p, k;
对于每组查询输出达到题目要求的最小步数,要求为:p=k+p+a[p],迭代到p>n为止;
思路:要是直接暴力时间复杂度为O(q*n)肯定会tle的,不过稍微加点技巧就好了;
先对500以内的k打下表,对于k>500的数,p每次都加k,所以最多500次就好了,那么时间复杂度只有O(500*q);
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int MAXN=1e5+10; 5 int a[MAXN], vis[510][MAXN]; 6 7 int main(void){ 8 int n, q, p, k; 9 scanf("%d", &n); 10 for(int i=1; i<=n; i++){ 11 scanf("%d", &a[i]); 12 } 13 for(int i=1; i<=500; i++){ 14 for(int j=n; j>0; j--){ 15 vis[i][j]=i+j+a[j]>n?1:vis[i][a[j]+j+i]+1; 16 } 17 } 18 scanf("%d", &q); 19 while(q--){ 20 scanf("%d%d", &p, &k); 21 if(k<=500) printf("%d\n", vis[k][p]); 22 else{ 23 int ans=0; 24 while(p<=n){ 25 p+=a[p]+k; 26 ans++; 27 } 28 printf("%d\n", ans); 29 } 30 } 31 return 0; 32 }
我就是我,颜色不一样的烟火 --- geloutingyu