刚开场卡了一会,凭借手速切出了前三题,,然后开始挂机。
D:点击打开链接
题意:给你n个数,这n个数是由每个数的前一个数*2,/3得到的(注意不是随机的,是按照一次乘2一次除3)。但是给你的这n个数是打乱的,要求恢复原本的顺序。
input
Copy
6 4 8 6 3 12 9
output
Copy
9 3 6 12 4 8
思路一:全排列,然后判断。 打了一遍玩玩,最长100个数,100!,,复杂度耗不起。
思路二:找规律,想先找最小的和最大的,然后递推(没做出来)
思路三:参考别人的题解,每一个数都可以计算出它包含多少个因子2,多少个因子3。然后利用结构体排个序,很容易就可以得到结果。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 105;
ll n,nn,k;
struct node{
ll two,three,num;
bool operator<(const node &p)const
{
if(three==p.three)
return two<p.two;
return three>p.three;
}
}a[maxn];
int main()
{
cin>>nn;
n = nn;
int cnt = 0;
while(n--)
{
node q;
cin>>k;
q.num = k;
int x=0,y=0;
while(k%3==0)
{
k /= 3;
x++;
}
while(k%2==0)
{
k /= 2;
y++;
}
q.two = y;
q.three = x;
a[cnt++] = q;
}
sort(a,a+cnt);
for(int i=0;i<cnt;i++)
cout<<a[i].num<<" ";
cout<<endl;
return 0;
}
第五题:点击打开链接
求有几个纯环(没有多余的边)。
思路:dfs,如果是纯环,那么一个节点有且只有2条边,其余看代码。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200005;
int n,m,ans;
vector<int>E[maxn];
bool vis[maxn],flag;
void dfs(int x)
{
if(E[x].size()!=2) flag = false;
for(int i=0;i<E[x].size();i++)
{
if(!vis[E[x][i]])
{
vis[E[x][i]] = 1;
dfs(E[x][i]);
}
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
int x,y;
cin>>x>>y;
E[x].push_back(y);
E[y].push_back(x);
}
for(int i=1;i<=n;i++)
{
//memset(vis,0,sizeof(vis));
if(!vis[i])
{
flag = 1;
dfs(i);
if(flag)
ans++;
}
}
cout<<ans<<endl;
return 0;
}
F题:点击打开链接
题目大意:输入n个数,求最大连续上升子序列(要记录序号)
真的是脑抽了,第一想法n^2dp,字符串瞎操作,果断TLE。。
#include<bits/stdc++.h>
#include<string>
using namespace std;
const int maxn = 200005;
typedef long long ll;
int n,ans,tot=0,pos;
ll a[maxn];
bool flag[maxn];
string s,sn;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lld",&a[i]);
}
ans = 0;
for(int i=0;i<n;i++)
{
if(flag[i]) continue;
flag[i] = 1;
pos = a[i];
tot = 1;
sn.clear();
string temp;
stringstream ss;
ss<<i+1;
ss>>temp;
sn += temp;
for(int j=i;j<n;j++)
{
if(n-j+tot<ans) break;
if(a[j]==pos+1)
{
tot++;
pos = a[j];
string temp;
stringstream ss;
ss<<j+1;
ss>>temp;
sn += temp;
}
}
if(tot>ans) {
ans = tot;
s = sn;
}
}
cout<<ans<<endl;
for(int i=0;i<s.length();i++)
cout<<s[i]<<" ";
return 0;
}
然后参考别人做法,O(nlogn)的,用了map维护的DP。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200005;
int n,a[maxn],pos,maxi=-1;
map<int,int> dp;
int main()
{
cin>>n;
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=n-1;i>=0;i--)
{
dp[a[i]] = max(dp[a[i]],dp[a[i]+1]+1);
if(dp[a[i]]>maxi)
{
maxi = dp[a[i]];
pos = a[i];
}
}
cout<<maxi<<endl;
for(int i=0;i<n;i++)
{
if(a[i]==pos) {
cout<<i+1<<" ";
pos++;
}
}
cout<<endl;
return 0;
}
这场DIV3总体来说还是比较简单的,但我菜,需努力。