Codeforces Round #479 (Div. 3)(A-F)題解
A. Wrong Subtraction
思路:簽到題,根據題意模擬即可。
時間複雜度:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
int main(){
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++){
if(n%10!=0) n--;
else n/=10;
}
cout<<n<<endl;
return 0;
}
B. Two-gram
思路:暴力,因爲所要求的子串長度爲,所以可以枚舉長度爲2的字符串。
時間複雜度:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
int a[26][26];
int main(){
int n;
cin>>n;
string s;
cin>>s;
for(int i=0;i<n-1;i++){
a[s[i]-'A'][s[i+1]-'A']++;
}
int mx=0,x,y;
for(int i=0;i<26;i++)
for(int j=0;j<26;j++){
if(a[i][j]>mx){
mx=a[i][j],x=i,y=j;
}
}
printf("%c%c\n",x+'A',y+'A');
return 0;
}
C. Less or Equal
思路:
我的解法:二分枚舉答案,即最大值最小化。時間複雜度:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
int a[N],n,k;
int check(int x){
int p=upper_bound(a+1,a+n+1,x)-a;
p--;
return p;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
int l=1,r=a[n];
while(l<=r){
int mid=(l+r)>>1;
if(check(mid)>=k) r=mid-1;
else l=mid+1;
}
if(check(l)!=k) puts("-1");
else printf("%d\n",l);
return 0;
}
實際上是我想多了,沒必要這麼麻煩,直接排序選第小的數即可,注意特判數的範圍是否則屬於。
時間複雜度: 。
這裏就不放代碼了。
D. Divide by three, multiply by two
思路:貪心+排序,因爲只有兩種操作:除以和乘以,所以含因子3越多的個數要越靠前,又因爲有乘2的操作,所以當的個數相同的時候,就取因子越少的數即可。
時間複雜度:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105+10,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
ll a[N];
pair<int,PII>b[N];
bool cmp(pair<int,PII> a,pair<int,PII> b){
return a.se.se==b.se.se?a.se.fi<b.se.fi:a.se.se>b.se.se;
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
ll x=a[i];
b[i].fi=i;
for(int j=2;j<=3;j++)
while(x%j==0){
if(j==2) b[i].se.fi++;
else b[i].se.se++;
x/=j;
}
}
sort(b+1,b+n+1,cmp);
for(int i=1;i<=n;i++)
printf("%lld ",a[b[i].fi]);
return 0;
}
E. Cyclic Components
題意:求給定無向圖的所有環(這裏的環是每個結點度數都爲2的環)個數。
思路:顯然使用,因爲題目不保證圖是連通的,所以用一個標記結點是否被訪問過,可能需要多次,每次若遍歷到已經標記過的結點而且所有結點度數都爲,則。
時間複雜度:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
vector<int>e[N];
int vis[N],d[N],ans,f;
void dfs(int u,int fa){
for(auto v:e[u]){
if(v==fa||d[v]!=2) continue;
//printf("%d->%d",u,v);
if(!vis[v]&&d[v]==2) vis[v]=1,dfs(v,u);
else if(vis[v]&&d[v]==2){
if(!f)
ans++,f=1;
else return;
}
}
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
e[u].push_back(v),e[v].push_back(u);
d[u]++,d[v]++;
}
for(int i=1;i<=n;i++){
if(!vis[i]&&d[i]==2) f=0,vis[i]=1,dfs(i,-1);
}
printf("%d\n",ans);
return 0;
}
F. Consecutive Subsequence
題意:求最長(連續遞增)子序列。
思路:這裏的連續遞增指得是子序列的數爲的相連的數相差1的形式。
根據題目顯然考慮解決此題,我們可以子序列的末尾的數,即最大值爲下標,令表示以元素結尾的最大長度。
因爲,所以考慮離散化,用儲存。
即。
因爲是順序遍歷,所以可以一邊輸入一遍更新。
對於輸出下標,則可以找到起始點.
然後順序掃一遍即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+100;
#define mst(a) memset(a,0,sizeof a)
int a[N];
map<int,int>mp;
int main(){
int n;
scanf("%d",&n);
int ans=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
mp[a[i]]=mp[a[i]-1]+1;
if(mp[a[i]]>mp[ans]) ans=a[i];
}
printf("%d\n",mp[ans]);
int st=ans-mp[ans]+1;
for(int i=1;i<=n;i++)
if(a[i]==st) printf("%d ",i),st++;
return 0;
}
此題有個坑點是用會 ,大概是哈希表建立的時間耗費較長?,不知道希望有人能說說。