1.Technocup 2021 - Elimination Round 1 A New Technique
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
#define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
/*
已知每行的相关顺序,
但不知道行的层次,通过列来找到行的层次
因为每一行的第一个元素就决定了该行剩余元素的排列,
所以确定每一行第一个元素的层次也就是,该行在第几行就行了
*/
typedef long long ll;
const int N=510;
int a[N][N],b[N][N];
int main()
{
IOS;
int t;cin>>t;
while(t--)
{
int n,m;cin>>n>>m;
rep(i,0,n)
rep(j,0,m)
cin>>a[i][j];
rep(i,0,m)
rep(j,0,n)
cin>>b[i][j];
vector<int>ans;
rep(i,0,n)
{
bool flag=false;
rep(j,0,n)
{
rep(k,0,m)
{
if(b[0][i]==a[j][k])
{
ans.pb(j);
flag=1;
break;
}
}
if(flag)
break;
}
}
rep(i,0,n)
{
rep(j,0,m)
cout<<a[ans[i]][j]<<" ";
cout<<endl;
}
}
return 0;
}
2.Codeforces Raif Round 1 (Div. 1 + Div. 2) B - Belted Rooms
算法想假了真的无语
假算法
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
#define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
const int N=3e5+10;
int id[N],od[N];
/*
假的算法,出度入度并不直接A能否返回A
*/
int main()
{
IOS;
int t;cin>>t;
while(t--)
{
memset(id,0,sizeof id);
memset(od,0,sizeof od);
int n;char s[N];
int cnta=0;
cin>>n>>s+1;
//第i个符号会影响第i和i+1个点.
// for(int i=1;i<n;i++)
// cout<<s[i]<<" ";
// cout<<endl;
for(int i=1;i<n;i++)
{
if(s[i]=='-')
{
cnta++;
id[(i+1)]++,id[i]++;
od[(i+1)]++,od[i]++;
}
else if(s[i]=='>')
{
id[(i+1)]++,od[i]++;
}
else if(s[i]=='<')
{
id[i]++,od[(i+1)]++;
}
}
if(s[n]=='-')
{
cnta++;
id[1]++,id[n]++;
od[1]++,od[n]++;
}
else if(s[n]=='>')
{
id[1]++,od[n]++;
}
else
{
id[n]++,od[1]++;
}
int cnt=0;
bool flag=true;
for(int i=1;i<=n;i++)
{
// cout<<id[i]<<" "<<od[i]<<endl;
if(!od[i]||!id[i])
{
flag=false;
}
if(id[i]&&od[i])
cnt++;
}
if(cnta)
cout<<cnt<<endl;
else
{
if(flag==false)
cout<<0<<endl;
else
cout<<cnt<<endl;
}
}
return 0;
}
正解
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
#define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
int main(){
IOS;
int t;cin>>t;
while(t--){
int n;cin>>n;
string s;cin>>s;
bool hasCw=false,hasAcw=false;
for(int i=0;i<n;i++){
if(s[i]=='<')
hasAcw=true;
if(s[i]=='>')
hasCw=true;
}
if(hasCw&&hasAcw){
int ans=0;
s+=s[0];//好巧妙,运用了string的特点,使得循环变成的顺序
for(int i=0;i<n;i++){
if(s[i]=='-'||s[i+1]=='-')
ans++;
}
cout<<ans<<endl;
}
else{
cout<<n<<endl;
}
}
return 0;
}
3.Educational Codeforces Round 96 (Rated for Div. 2) C. Numbers on Whiteboard
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
#define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
const int N=3e5+10;
int main()
{
IOS;
int t;cin>>t;
while(t--)
{
int n;cin>>n;
cout<<2<<endl;
if(n==2)
cout<<2<<" "<<1<<endl;
else
{
cout<<n-1<<" "<<n<<endl;
for(int i=n-2;i>=1;i--)
cout<<i<<" "<<i+2<<endl;
}
}
return 0;
}
4.Codeforces Round #675 (Div. 2) B. Nice Matrix
( 观察到,若让矩形是回文的必有a[i][j]=a[n-i+1][j]=a[i][m-j+1],(数组下标为a[1sim n,1sim m])\ a[i][j]=a[n-i-1][j]=a[i][m-j-1],(数组下标为a[0sim n-1,0sim m-1])\ )
想假的算法
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
#define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
const int N=110;
int a[N][N];
int main()
{
IOS;
int t;cin>>t;
while(t--)
{
int sum=0;
memset(a,0,sizeof a);
int n,m;cin>>n>>m;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>a[i][j];
sum+=a[i][j];
}
}
// cout<<sum<<endl;
sum=sum/m/n;
// cout<<sum<<endl;
ll cnt=0;
rep(i,a,n)
{
rep(j,a,m)
{
if(sum>=a[i][j])
cnt+=sum-a[i][j];
else
cnt+=a[i][j]-sum;
}
}
cout<<cnt<<endl;
}
return 0;
}
/*
4 2
4 2
2 4
4 2
2 4
10+26+48==84/12==7
6+5+4+3
+2+1+1+2+3+4+11==21+10+11==42
对于
3*4
a[2][2]=a[2][2]=a[1][3]=a[2][3]
*/
正解
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
#define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
const int N=110;
int a[N][N];
int main()
{
IOS;
int t;cin>>t;
while(t--)
{
int n,m;cin>>n>>m;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>a[i][j];
}
}
ll cnt=0;
rep(i,a,n)
{
rep(j,a,m)
{
vector<int>ans;
ans.pb(a[i][j]);
ans.pb(a[n-i-1][j]);
ans.pb(a[i][m-j-1]);
sort(ans.begin(),ans.end());
// for(auto x:ans)
// cout<<x<<" ";
// cout<<endl;
cnt+=ans[1]-ans[0];
cnt+=ans[2]-ans[1];
a[i][j]=a[n-i-1][j]=a[i][m-j-1]=ans[1];
}
}
cout<<cnt<<endl;
}
return 0;
}
6.Codeforces Round #670 (Div. 2) B. Maximum Product
( 一开始这题完全没有思路,一开始认为是从原数组中不打乱顺序求出5个数乘积的最大值(被迷惑了,大雾)\ 后来看了人家的题解,发现虽然这五个数是有顺序的,但题目没说不能乱序啊!拿出5个数来,数字的下标当然不同了\ 分析符号,首先降序排序 1.如果全正或全负,前五个数的乘积最大,如果升序排序则要多写一个乘积\ 2.当有正有负时,负数的个数必须是0,2,4,5,其中0,5已经被讨论过了 所以再取2和4个负数,再乘积,最后比较3个乘积的最大值输出即可 )
法一
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
#define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
#define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
const int N=111000;
int t;
ll n;
ll a[N];
bool cmp(ll a,ll b)
{
return a>b;
}
int main() {
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;++i){
cin>>a[i];
}
sort(a+1,a+1+n,cmp);
ll cnt1=a[1]*a[2]*a[3]*a[4]*a[5];
ll cnt2=a[1]*a[2]*a[3]*a[n]*a[n-1];
ll cnt3=a[1]*a[n]*a[n-1]*a[n-2]*a[n-3];
cout<<max(cnt1,max(cnt2,cnt3))<<endl;
}
return 0;
}
法二
#include<bits/stdc++.h>
using namespace std;
long long ans,a[100005];
int main() {
int t;
scanf("%d",&t);
while(t--){
int n;
long long mx=-1e9;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),mx=max(mx,a[i]);
sort(a+1,a+n+1,[](long long x,long long y){return abs(x)>abs(y);});
if(mx<0){
cout<<a[n]*a[n-1]*a[n-2]*a[n-3]*a[n-4]<<'
';
continue;
}
ans=a[1]*a[2]*a[3]*a[4]*a[5];
//这是绝对值最大的五个数的乘积
/*
-3 -2 -1 1 2 3 4 5
5 4 3 -3 2 -2 1 -1
*/
//把前五个绝对值最大的数中的某一个数替换成后边n-5中的某一个数
for(int i=6;i<=n;i++)
{
for(int j=1;j<=5;j++)
{
long long tmp=a[i];//想要更换的那个数
for(int k=1;k<=5;k++){
if(k!=j)tmp*=a[k];
}
ans=max(ans,tmp);
}
}
printf("%lld
",ans);
}
return 0;
}
7.CodeForces - 1405 B Array Cancellation
( 法一.\ O(N)跑一遍前缀和,如果前缀和小于0,代表必须付出的代价,累计abs(代价),前缀和清空\ 最后输出代价。\ 法二.\ 定义后缀和c[i]=a[i]+a[i+1]+...+a[n]\ 最后有a[0]=a[1]=a[2]=...=a[n]=0,所以有c[n]=c[n-1]=...=c[1]=0; 因为a[i]=c[i]-c[i+1],a[j]=c[j]-c[j+1],当i<j时,尽量让a[i]--,a[j]++\ 就有c[i+1]++,c[j]++;\ 即c[i+1]...c[j]这段连续的数组越大越好.处理后缀和数组,输出最大后缀和就是ans. )
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+5;
ll a[maxn];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
ll ans=0,sum=0;
for(int i=0;i<n;i++)
{
ans+=a[i];
if(ans<0)
sum+=-ans,ans=0;
}
cout<<sum<<endl;
}
return 0;
}
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
#define rep(i,a,n) for(int i=0;i<n;i++)
#define per(i,a,n) for(int i=n;i>=0;i--)
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
const int N=111000;
ll a[N];
ll sum;
int main()
{
IOS;
int t;cin>>t;
while(t--)
{
int n;cin>>n;
ll ans=-1e6;
for(int i=n;i>=1;i--)
cin>>a[i];
for(int i=1;i<=n;i++)
{
sum+=a[i];
ans=max(ans,sum);
}
cout<<ans<<endl;
}
return 0;
}
8.CodeForces - 1392 C Omkar and Waterslide
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
#define rep(i,a,n) for(int i=0;i<n;i++)
#define per(i,a,n) for(int i=n;i>=0;i--)
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
/*
思路:(假思路)
假了,wok,最烦这种想一会发现对不上题。
如果数组最大最小值相等输出0
否则使用双指针遍历原始数组
找到区间[i,j],该区间所有元素的最大值一定小于max,求出区间[i,j]中最小的元素a,
ans=max-a
别人的思路
题意:目的:数组不递减,可以让连续的一段区间[l,r],上,各个元素自增1
10 5 3 7 2 10
1.让 5 3 7 2 变成10;
2.让 5 3 变成7 2变成7;
3.让 3变成5
上述操作可以写成
if(a[i]>a[i+1])
sum+=a[i]-a[i+1];
输出sum即为ans
*/
const int N=2e5+10;
int a[N];
int main()
{
IOS;
int t;cin>>t;
while(t--)
{
int n;cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
ll sum=0;
for(int i=1;i<n;i++)
{
if(a[i]>a[i+1])
sum+=a[i]-a[i+1];
}
cout<<sum<<endl;
}
return 0;
}