题意:知足下面的条件,输出替换后的最小的数,反之输出-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; }