A题上来就是读题,读完就明白了。
#include <bits/stdc++.h>
#define LOCAL
#define ll long long
#define lll unsigned long long
#define MAX 1000009
#define eps 1e-8
#define INF 0x7fffffff
#define mod 1000000007
using namespace std;
int a[MAX];
int b[MAX];
int ans[MAX];
int main()
{
int u,v,n;
int k = 0;
cin>>n;
for(int i = 1;i<=n*n;i++)
{
cin>>u>>v;
if(!a[u]&&!b[v])
{
ans[k++] = i;
a[u] = 1;
b[v] = 1;
}
else
{
continue;
}
}
for(int i = 0;i<k;i++)
{
cout<<ans[i]<<endl;
}
return 0;
}
B题就是模拟,直到n个数,全都被遍历到,最开始错了一下,是我认为遍历完的状态是最大的被遍历,实际不是
10
5 0 0 1 3 2 2 2 5 7
这组被卡。
#include <bits/stdc++.h>
#define LOCAL
#define ll long long
#define lll unsigned long long
#define MAX 1000009
#define eps 1e-8
#define INF 0x7fffffff
#define mod 1000000007
using namespace std;
int a[MAX];
int vis[MAX];
int n;
int main()
{
int n;
cin>>n;
int _max = -1;
int flag = 0;
for(int i = 1; i<=n; i++)
{
cin>>a[i];
if(_max < a[i])
{
_max = a[i];
flag = i;
}
}
int num = 0;
int ans = 0;
int k = 0;
while(num<n)
{
if(k==0)
{
ans++;
for(int i = 1; i<=n; i++)
{
if(a[i]<=num&&!vis[i])
{
vis[i] = 1;
num++;
}
}
k = 1;
}
else
{
ans++;
for(int i = n; i>=1; i--)
{
if(a[i]<=num&&!vis[i])
{
vis[i] = 1;
num++;
}
}
k = 0;
}
// cout<<k<<endl;
// for(int i = 1;i<=n;i++)
// {
// cout<<i<<" "<<vis[i]<<" ";
// }
// cout<<endl;
}
printf("%d\n",ans - 1);
return 0;
}
/*
10
5 0 0 1 3 2 2 2 5 7
*/
C题是我比较没思路的一道题,给的是乱序,我们要找到其中的性质。
#include <bits/stdc++.h>
#define LOCAL
#define ll long long
#define lll unsigned long long
#define MAX 10000009
#define eps 1e-9
#define INF 0x7fffffff
#define mod 1000000007
using namespace std;
/*
有一个已知的性质就是最大的两个一定在数组中,找出两个最大的,进行GCD,然后在用第三大的与这两个进行gcd
依次类推。
*/
int x[MAX];
int main()
{
int n;
vector<int>a;
map<int,int>num;
cin>>n;
for(int i = 0; i<n*n; i++){
cin>>x[i];
num[x[i]]++;
}
sort(x , x + n*n);
reverse(x , x + n*n);
for(int i = 0; i<n*n; i++)
{
if(num[x[i]]>0)
{
cout<<x[i]<<" ";
for(int j = 0; j<a.size(); j++)
{
num[__gcd(x[i],a[j])]-=2;
}
a.push_back(x[i]);
num[x[i]]--;
}
}
return 0;
}
D题稍微变点型的LIS,而且n^2的就可以。我们在有限的循环下,会发现,当重复一定次数的时候,每次增加的长度,是原数组出现最多次数的数。
所以呢,我们循环100次先,然后再加上单位每次多得长度。
#include <bits/stdc++.h>
#define LOCAL
#define ll long long
#define lll unsigned long long
#define MAX 1000009
#define eps 1e-8
#define INF 0x7fffffff
#define mod 1000000007
using namespace std;
int a[MAX];
int dp[MAX];
int num[MAX];
int main()
{
int n,T;
int ans = -1;
int _max = 1;
int sum = 1;
scanf("%d%d",&n,&T);
for(int i = 0; i<n; i++)
{
scanf("%d",&a[i]);
num[a[i]]++;
}
for(int i = 0; i<n; i++)
{
sum = max(sum , num[a[i]]);//最长的一定会是按照单位数组出现最多的那个数
}
fill(dp,dp+MAX,1);
int t = min(T,100);
for(int i = 0; i<t*n; i++)
{
int ii = i%n;
for(int j = 0; j<i; j++)
{
int jj = j%n;
if(a[ii]>=a[jj])
{
dp[i] = max(dp[i],dp[j] + 1);
}
}
if(_max<dp[i])
{
_max = dp[i];
}
}
printf("%d\n",_max + (T - t)*sum);//循环t次的LIS + (T - t)*单位最多次数。
return 0;
}