Educational Codeforces Round 89 (Rated for Div. 2)
阿新 • • 發佈:2020-07-10
Educational Codeforces Round 89 (Rated for Div. 2)
這套題總的來說都不是很難,和昨天寫的那套有一定的相似程度,就是演算法比較少,思維比較多。
A B 沒有昨天做的那麼順,還是卡了一會,尤其是B,還把題目看錯了
C 題倒是做的比較順,但是花的時間還是長了一點點
D 題不是很難,花的時間過於多了,導致E題結束之後才寫完
這場的ABCDE都可以補一下,沒什麼演算法,主要靠思維+細心觀察
這個假設 \(x\) 個 sword,\(y\) 個 shovel,
那麼最後就是 $2*x+y<=a$ \(x+2*y<=b\)
所以就可以把 \(x+y\) 求出來了,但是注意要和 \(a、b\) 取一個min。
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f #define debug(x) printf("debug:%s=%d\n",#x,x); //#define debug(x) cout << #x << ": " << x << endl using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 5e5+10; int main(){ int t; scanf("%d",&t); while(t--){ int n,m; scanf("%d%d",&n,&m); int ans=min((n+m)/3,min(n,m)); printf("%d\n",ans); } return 0; }
題目大意:
首先在 \(x\) 位置有一個1,你有 \(m\) 次操作,對於第 \(i\) 次操作,你可以交換 \([li,ri]\) 的任意兩個數,注意這兩個數可以相同,也就是說你可以不進行交換。問最後可以出現1的位置有多少個?
題解:
這個其實就是一個區間不斷往外擴充套件,第一次的區間就是 \([x,x]\) ,之後的操作區間如果和之前得到的區間有重疊,那麼就可以加入之前的這個區間,最後輸出區間的長度即可。
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f #define debug(x) printf("debug:%s=%d\n",#x,x); //#define debug(x) cout << #x << ": " << x << endl using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 5e5+10; int main(){ int t; scanf("%d",&t); while(t--){ int n,x,m; scanf("%d%d%d",&n,&x,&m); int l=x,r=x; for(int i=1;i<=m;i++){ int a,b; scanf("%d%d",&a,&b); if((a<=r&&a>=l)||(b<=r&&b>=l)||(b>=r&&a<=r)) { l=min(l,a); r=max(r,b); } } printf("%d\n",r-l+1); } }
題目大意:
給你一個 \(n*m\) 的矩陣,從 \((1,1)\) 開始走,每一步只能往右或者往下走,最後走到 \((n,m)\) ,給你這個矩陣每一個位置的值,這個值取0或者1,你可以對這個矩陣的值進行改變,問最少改變多少個值,可以讓第一步的位置和最後一步的位置的值相同,第二步的位置和倒數第二個位置的值相同,以此類推。
題解:
這個不好講,看程式碼吧
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
#define debug(x) printf("debug:%s=%d\n",#x,x);
//#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn =55;
int a[maxn][maxn],num[110],sum[110];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m,now=0;
memset(sum,0,sizeof(sum));
memset(num,0,sizeof(num));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++){
int x=i,y=1;
++now;
while(true){
sum[now]++;
if(a[x][y]) num[now]++;
x--,y++;
if(x<1||y>m) break;
}
}
for(int i=2;i<=m;i++){
int x=n,y=i;
++now;
while(true){
sum[now]++;
if(a[x][y]) num[now]++;
x--,y++;
if(x<1||y>m) break;
}
}
int ans=0;
// printf("now=%d\n",now);
for(int i=1;i<=now/2;i++){
ans+=min(num[i]+num[now-i+1],sum[i]+sum[now-i+1]-num[i]-num[now-i+1]);
// printf("i=%d ans=%d\n",i,ans);
}
printf("%d\n",ans);
}
}
這個不是很難,仔細分析吧。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
#define debug(x) printf("debug:%s=%d\n",#x,x);
//#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn =4e3;
int phi[maxn],pri[maxn],cnt,v[maxn];
void init() {
cnt = 0;
phi[1] = 1;
memset(v,0,sizeof(v));
for (int i = 2; i < maxn; ++i) {
if (!v[i]) {
v[i] = i;
pri[cnt++] = i;
}
for (int j = 0; j < cnt; ++j) {
if (1ll * i * pri[j] >= maxn) break;
v[i * pri[j]] = pri[j];
}
}
}
int a[500005],ans1[500005],ans2[500005];
int gcd(int x,int y){
return y==0?x:gcd(y,x%y);
}
int main(){
int n;
init();
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x,f=0;
scanf("%d",&x);
int y=x;
for(int j=0;j<cnt;j++){
while(x%pri[j]==0){
f = pri[j];
x/=pri[j];
}
if(f) break;
}
if(!f) f=x,x=1;
ans1[i]=x,ans2[i]=f;
if(ans1[i]==1||ans2[i]==1||gcd(ans1[i]+ans2[i],x)!=1) ans1[i]=ans2[i]=-1;
}
for(int i=1;i<=n;i++) printf("%d ",ans1[i]);
printf("\n");
for(int i=1;i<=n;i++) printf("%d ",ans2[i]);
printf("\n");
}
這個你首先要判斷有沒有方案,如果有方案則求出每一個區間的最小區間,然後用組合數求解。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
#define debug(x) printf("debug:%s=%d\n",#x,x);
//#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn =2e5+10;
const int mod = 998244353;
int l[maxn],r[maxn];
int a[maxn],b[maxn];
struct node{
int v,id;
node(int v=0,int id=0):v(v),id(id){}
bool operator<(const node & a)const {
return a.v<v;
}
};
priority_queue<node>que;
map<int,int>mp;
int main(){
int n,m,f=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),que.push(node(a[i],i));
for(int i=1;i<=m;i++) scanf("%d",&b[i]);
b[m+1]=inf;
for(int i=1;i<=m;i++){
while(!que.empty()){
node u = que.top();
// printf("u.v=%d\n",u.v);
if(u.v<b[i+1]) r[i]=max(r[i],u.id),que.pop();
else break;
}
if(!r[i]) f=1;
}
for(int i=1;i<=n;i++){
if(a[i]<b[1]) f = 1;
mp[a[i]]=i;
}
// debug(f);
for(int i=1;i<=m;i++) {
l[i]=mp[b[i]];
if(!l[i]) f = 1;
if(l[i]>r[i]) f = 1;
if(l[i]<=r[i-1]) f = 1;
}
l[1]=1;
if(f) printf("0\n");
else{
ll ans = 1;
for(int i=2;i<=m;i++){
ll res = l[i]-r[i-1];
ans=res*ans%mod;
}
printf("%lld\n",ans);
}
return 0;
}