題意:知足下面的條件,輸出替換後的最小的數,反之輸出-1。c++
暴力數組
#include <bits/stdc++.h> #include <iostream> using namespace std; const int maxn=2e4+5; //int a[maxn][maxn]; #define ll long long int main(){ int n; cin>>n; while(n--){ ll m; cin>>m; int ans=0; while(m!=1){ ans++; if(m%2==0) m/=2; else if(m%3==0) m=m/3*2; else if(m%5==0) m=m/5*4; else { ans=-1; break; } } cout<<ans<<endl; } return 0; }
題意:經過合併一些數,使得能被3整除的最多個數是多少。spa
想的深刻一點,會發現其實能夠變成只包含1,2序列,將數組預處理%上3,找出能被3整除的,而後把獲得的只包含1,2的序列合併成3就簡單多了,加上這裏合併出來的3就是答案了3d
#include <bits/stdc++.h> #include <iostream> using namespace std; const int maxn=2e4+5; int a[maxn]; #define ll long long //sync_with_stdio (false); int main(){ int n,m; cin>>n; while(n--){ cin>>m; int index=0; for(int i=0; i<m; i++){ int x=0; cin>>x; if(x%3!=0) a[index++]=x%3; } int ans=m-index; int y1=0,y2=0; for(int i=0; i<index; i++){ if(a[i]==1) y1++; else y2++; } if(y1>=y2){ ans+=(y2+(y1-y2)/3); } else ans+=(y1+(y2-y1)/3); cout<<ans<<endl; } return 0; }
C - Lose it!code
題意:刪除最少的元素,使的數組中的元素都是由下面的序列組成的,換句話說:該序列包含了n個該子序列xml
4,8,15,16,23,42blog
題目看錯,反應過來,dp寫錯,不是42元素前面有4,8,15,16,23元素,而是要有這個序列,是順序要求的 qwqci
wa了的代碼:
#include <bits/stdc++.h> #include <iostream> using namespace std; const int maxn=2e4+5; int a[50]; #define ll long long //sync_with_stdio (false); int main(){ memset(a,0,sizeof(a)); int n,m=600000; cin>>n; int ans=0; for(int i=0; i<n; i++){ float x; cin>>x; if(x/4==1) a[0]++; else if(x/8==1) a[1]++; else if(x/15==1) a[2]++; else if(x/16==1) a[3]++; else if(x/23==1) a[4]++; else if(x/42==1) a[5]++; if(x==42){ if(a[0]>0&&a[1]>0&&a[2]>0&&a[3]>0&&a[4]>0&&a[5]>0){ a[0]--,a[1]--,a[2]--,a[3]--,a[4]--,a[5]--; ans++; } } } ans=n-ans*6; cout<<ans<<endl; return 0; }
簡單dp(ac)
#include <bits/stdc++.h> #include <iostream> using namespace std; const int maxn=2e4+5; int a[50]; map<int,int> mp; #define ll long long // int main(){ std::ios::sync_with_stdio (false); memset(a,0,sizeof(a)); mp[4]=0,mp[8]=1,mp[15]=2,mp[16]=3,mp[23]=4,mp[42]=5; int n,m=600000; cin>>n; int ans=0; for(int i=0; i<n; i++){ int x; cin>>x; int index=mp[x]; if(mp[x]==0||a[index-1]>a[index]) a[index]++; } //cout<<ans<<endl; ans=n-a[5]*6; cout<<ans<<endl; return 0; }
題意:刪除一些點,不超過總數的一半,使剩下的點和至少和一個刪除的點有一天邊。
開始時,一句關鍵的畫沒看懂,把題目讀偏了,看了一下別人的題解,有人說是二分圖,其實不是的,只是作法有些相似,用dfs把相鄰邊染成不一樣顏色,但其實這裏相鄰點能夠是相同顏色,只有當相鄰點顏色不一樣時,才時二分圖,其實這也是二分圖的斷定方法。
#include <bits/stdc++.h> #include <iostream> using namespace std; #define ll long long const int maxn=2e5+5; //int a[maxn],tmp[maxn]; pair<int,int> p; map<int,int> mp; //map<int,int> ::iterator it; //vector<pair<int,int> >::iterator its; vector<int> edge[maxn]; bool vis[maxn]; set<int> a,b; set<int> ::iterator it; void dfs(int u,int flag){ vis[u]=1; if(flag) a.insert(u); else b.insert(u); for(int i=0; i<edge[u].size(); ++i){ if(!vis[edge[u][i]]) { dfs(edge[u][i],!flag); } } } void init(int n){ a.clear(),b.clear(); for(int i=1; i<=n; ++i) edge[i].clear(),vis[i]=0; } int main(){ std::ios::sync_with_stdio (false); int q,n,m,u,v; cin>>q; while(q--){ cin>>n>>m; init(n); for(int i=0; i<m; ++i){ cin>>u>>v; edge[u].push_back(v),edge[v].push_back(u); } dfs(1,1); if(a.size()>b.size()){ cout<<b.size()<<"\n"; for(it=b.begin(); it!=b.end(); ++it) cout<<*it<<" "; cout<<"\n"; } else{ cout<<a.size()<<"\n"; for(it=a.begin(); it!=a.end(); ++it) cout<<*it<<" "; cout<<"\n"; } } return 0; }