1 2 3 4

2020-12-14cf 总结

我写了那些题目:

 

 

 

https://codeforc.es/problemset/problem/1366/D            

Two Divisors

 

这个题目乍一看很难,是个猜测规律的题,实际是可以严格的数学证明

问d1和d2是ans的两个约数,你可以选择两个非1的约数------gcd(d1+d2,ans)

有一个公式,gcd(d1+d2,d1*d2),这样一来就可以了,d1随便找的质数,分解起来,d1*d2就是ans了,可惜想不到啊

gcd本质上是质数的手段,暂时先这样推测吧。。。

 

 

代码如下

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 2e5+111;
const int Maxn = 1e7+11;
int prime[Maxn];
int Mark[Maxn + 1];

int sieve() {
    int p = 0;
    Mark[0] = 1; Mark[1] = 1;
    for (int i = 2; i < Maxn; i++){
        if (Mark[i] == 0) {
            prime[p++] = i;
        }
        for (int j = 0; j < p && prime[j] * i < Maxn; j++){
            Mark[i * prime[j]] = 1;
            if (i % prime[j] == 0) {
                break;
            }
        }
    }
    return p;
}



vector<int>a,b,c;



int main(){
	int chal = sieve();
	
	int t;
	cin>>t;
	for(int k=0;k<t;k++){
		int x;
		cin>>x;
		if(!Mark[x]){
			a.push_back(-1);
			b.push_back(-1);
			continue;
		}
		int ans = 0;
		for(int i=0;i<1000 && prime[i] <= x;i++){
			int p = prime[i];
			if(x % p == 0){
				ans = p;
				while(x%p == 0){
					x /= p;
				}
				break;
			}
		}
		if(x > 1){
			a.push_back(x);
			b.push_back(ans);
		}
		else{
			a.push_back(-1);
			b.push_back(-1);
		}
	}
	for(int i=0;i<a.size();i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	for(int i=0;i<a.size();i++){
		cout<<b[i]<<" ";
	}
	cout<<endl;
	return 0;
} 

  

 

 

 

https://codeforc.es/problemset/problem/1366/C

Palindromic Paths

这个题也很有趣,问你在01矩阵里,从左上角到右下角,走的路径的01串要求是回文的,问你最少反转几个01就可以。

 

 

 

可以发现圈住的地方步数是一样的,所以只要左上和右下比较一下就行。

#include<iostream>
using namespace std;
typedef long long ll;
int list[200][200];


int n,m;
int a[2000];
int b[2000];


int main(){
	ll t;
	cin>>t;
	while(t--){
		cin>>n>>m;
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				cin>>list[i][j];
				
			}
		} 
		for(int i=0;i<n*m;i++){
			a[i] = b[i] = 0;
		}
		
		
		int be = 0;
		
		for(int i=0;i<n;i++){
			be = i+1;
			for(int j=0;j<m;j++){
				if(list[i][j]) a[be]++;
				else b[be]++;
				be++;
			}
		}
		int len = n+m-1;
		int ans = 0;
		
		for(int i=1;i<len/2 + 1;i++){
			int x = i;
			int y = len - i + 1;
			ans += min(a[x] + a[y],b[y] + b[x]);
		}
		cout<<ans<<endl<<endl;
	}
	return 0;
}

  

 

 

 

https://codeforc.es/problemset/problem/1435/C

Perform Easily

 

又是原题打乱排序尺取,

#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
const ll INF = 1e16;
const int maxn = 2e5+11;
set<int>ss;

struct Node {
	ll val;
	int id;
	Node(ll a,int b) : val(a),id(b) {}
};

vector<Node>ins;
queue<Node>que;



int n;

int a[20];
ll list[maxn];
bool bml(Node a,Node b) {
	return a.val < b.val;
}

int vis[maxn];



int main() {
	for(int i=0; i<6; i++) {
		cin>>a[i];
		ss.insert(a[i]);
	}
	int len = ss.size();
	
	cin>>n;
	for(int i=0; i<n; i++) {
		cin>>list[i];
	}



	for(int i=0; i<n; i++) {
		for(int j=0; j<6; j++) {
			ll x = list[i] - a[j];
			if(x < 0) x = INF;
			ins.push_back(Node(x,i));
		}
	}

	sort(ins.begin(),ins.end(),bml);

	int cnt = 0;
	ll ans = INF;

	for(int i=0; i<ins.size(); i++) {
		Node a = ins[i];
		if(vis[a.id] == 0)	cnt++;
		vis[a.id] ++;
		que.push(a);
		
		if(cnt == n){
			while(que.size()){
				Node aa = que.front();
				que.pop();
				
				ans = min(ins[i].val - aa.val,ans);
				
				
				
				vis[aa.id]--;
				if(vis[aa.id] == 0){
					cnt--;
					break;
				}
			}
		}
	}
	
	cout<<ans<<endl;
	return 0;
}




  

 下周南京,我要拿奖,我能拿奖,我必定拿奖

 

posted @ 2020-12-14 21:31  Lesning  阅读(81)  评论(0编辑  收藏  举报