Codeforces Round #479 (Div. 3)解題報告
阿新 • • 發佈:2018-05-14
ive 操作規則 false iostream 數組 pre equal sort 報告
題目鏈接: http://codeforces.com/contest/977
A. Wrong Subtraction
題意
給定一個數x,求n次操作輸出。操作規則:10的倍數則除10,否則減1
直接寫,手速題,沒啥好說的
B. Two-gram
題意
求出現次數最多的連續兩個字符
還是簽到題,我居然很麻煩地用了map,= =算了,思路暢通都無所謂了
#include <iostream> #include<stdio.h> #include<algorithm> #include<string.h> #include<stringView Code> #include<map> using namespace std; int main() { char a[100],s[5],ss[5]; int n; while(cin>>n) { cin>>a; map<string,int>mp; int MAX=-1; for(int i=0;i<strlen(a)-1;i++) { s[0]=a[i]; s[1]=a[i+1]; mp[s]++; //cout<<s<<endl; if(mp[s]>MAX) MAX=mp[s],ss[0]=a[i],ss[1]=a[i+1]; } cout<<ss[0]<<ss[1]<<endl; } return 0; }
C. Less or Equal
題意
給一串數組,是否找到一個數x,找到k個數字<=x,找到輸出x,不能輸出-1。
第二組,要找到兩個數字,排序後出現1,3,3,會出現三個數字小於等於3,所以不能找到。
註意下k==0的時候就好了,沒啥好說的
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <map> #define ll long long using namespace std; const int maxn=2e5+10; int a[maxn]; int main() { int m,k; while(cin>>m>>k) { for(int i=0;i<m;i++) cin>>a[i]; sort(a,a+m); if(k==0) { if(a[0]==1) puts("-1"); else cout<<a[0]-1<<endl; } else if(k==m) cout<<a[k-1]<<endl; else { if(a[k-1]==a[k]) puts("-1"); else cout<<a[k-1]<<endl; } } return 0; }
D. Divide by three, multiply by two
題意
直接看樣例吧 4 8 6 3 12 9 把這個序列排成一個這樣的序列, 前一位是後一位數的一半或者3倍,所以排序後是這樣 9 3 6 12 4 8
dfs或者直接雙重for循環都可以,不過賽後看到個數學思路的題解,覺得很有靈性= =
直接按對3有更多約數的多少來排(前一位是後一位的3倍),有相同個則從小到大(也就是前一位是後一位數的一半)
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <map> #define ll long long using namespace std; const int maxm=2e5+10; const int maxn=1e5+10; ll a[105]; ll s(ll num) { ll cnt=0; while(num%3==0) { cnt++; num/=3; } return cnt; } bool cmp(ll x,ll y) { if(s(x)!=s(y)) return s(x)>s(y); else return x<y; } int main() { int n; while(cin>>n) { for(int i=0;i<n;i++) cin>>a[i]; sort(a,a+n,cmp); for(int i=0;i<n;i++) printf("%lld%c",a[i],i==n-1?‘\n‘:‘ ‘); } }
E. Cyclic Components
題意
給定點的個數和各條邊,問有多少個環
既然是環,一個點就會對應兩次啊,直接並查集啊,巴拉巴拉,水水水就過去了
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <map> #define ll long long using namespace std; const int maxn=2e5+10; int pre[maxn],edg[maxn],cnt; struct node { int u,v; }a[maxn]; void iint() { for(int i=0;i<maxn;i++) pre[i]=i; } int ffind(int x) { if(x==pre[x]) return x; return pre[x]=ffind(pre[x]); } void join(int x,int y) { x=ffind(x),y=ffind(y); if(x!=y) pre[x]=y; else cnt++; } int main() { int m,n; while(cin>>m>>n) { iint(); memset(edg,0,sizeof(edg)); for(int i=0;i<n;i++) { cin>>a[i].u>>a[i].v; edg[a[i].u]++; edg[a[i].v]++; } cnt=0; for(int i=0;i<m;i++) { if(edg[a[i].u]==2&&edg[a[i].v]==2) join(a[i].u,a[i].v); } cout<<cnt<<endl; } return 0; }
F. Consecutive Subsequence
題意
給你一個數組找出最長的遞增子序列的長度以及下標位置。
例如: 第一組樣例 3 3 4 7 5 6 8
最長的子序列為3 4 5 6,長度為4。
下標為1 3 5 6或2 3 5 6
覺得dp才是正解,貼個別人的http://www.bubuko.com/infodetail-2595514.html
可是比賽時候不知道為什麽被我map玄學給過了2333
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <map> #define ll long long using namespace std; const int maxn=2e5+10; int a[maxn]; int main() { ios::sync_with_stdio(false); int n,tmp; while(cin>>n) { map<int,int>mp; int max_pos=-1,Max=-1; for(int i=1;i<=n;i++) { cin>>a[i]; mp[a[i]]=mp[a[i]-1]+1; if(mp[a[i]]>Max) Max=mp[a[i]],tmp=a[i],max_pos=i; } int u=tmp-Max+1; cout<<Max<<endl; bool f=true; for(int i=1;i<=max_pos;i++) { if(a[i]==u) { if(f) cout<<i,f=false; else cout<<" "<<i; u++; } } cout<<endl; } return 0; }
Codeforces Round #479 (Div. 3)解題報告