A:判断一个数是否有大于1的奇因子。奇数直接yes,偶数判断一下是不是2的幂
while(t--) {
		ll n;
		cin >> n;	
		if(n%2==0)
		{
			while(!(n&1))
			{
				n/=2;
			}
			if(n == 1)
			cout << "NO" << endl;
			else cout << "YES" << endl;
		}
		else
			cout << "YES" << endl;
 
	}

B:判断一个数n能不能用2020和2021表示。分别记录n除以2020和mod2020的值,比较大小。
while(t--) {
		int n;cin >> n;
		int tmp=n/2020,temp=n%2020;
		if(temp<=tmp) cout << "YES" << endl;
		else cout <<"NO"<< endl; 
 
	}

C:给出男生、女生的总个数 a,b 和配对的组数 k。其中(x,y) 为一对,x表示男生编号,y表示女生编号。询问找出 2 个组且其中的男生女生不重复的挑选方法数。
思路1:统计男女生每个编号出现的次数cnta,cntb,当我们选择一对后,剩下还能选择就是k-(cnta-1)-(cntb-1)-1,cnta-1代表除了当前这一对男生可与其它女生配对的数量,cntb-1同理,最后再减一是减去我们最开始选择的那一对,剩下差值就为我们还能选择的对数。
while(t--) {
		int aa,bb,k; cin >> aa >> bb >> k;
		memset(vis1,0,sizeof(vis1));
		memset(vis2,0,sizeof(vis2));
		for(int i=1;i<=k;i++) 
		{
			cin >> a[i];
			vis1[a[i]]++;
		}
		for(int i=1;i<=k;i++) 
		{
			cin >> b[i];
			vis2[b[i]]++;
		}
		ll ans=0;
		for(int i=1;i<=k;i++)
		{
			ll cnt1=vis1[a[i]]-1,cnt2=vis2[b[i]]-1;
			ans+=k-cnt1-cnt2-1;
		}
		cout << ans / 2 << endl;
 
	}

思路2:所有情况减去重复的情况。(long long)
while (T--) {
	cin >> a >> b >> k;
	for (int i = 0; i <= a; i++)A[i] = 0;
	for (int i = 0; i <= b; i++)B[i] = 0;
	for(int i = 1; i <= k; i++) {
		int x;
		cin >> x;
		A[x]++;
	}
	for(int i = 1; i <= k; i++) {
		int x;
		cin >> x;
		B[x]++;
	}
	ll ans = 1ll * k * (k - 1) / 2ll;
	for(int i = 1; i <= a; i++) {
		ans -= 1ll * A[i] * (A[i] - 1ll) / 2ll;
	}
	for(int i = 1; i <= b; i++) {
		ans -= 1ll * B[i] * (B[i] - 1ll) / 2ll;
	}
	cout << ans << endl;
}

D:删除内存和至少为m的应用,问最少将失去多少方便点。方便点要么为1要么为2,将每个应用按照方便点分类再排序,方便点为2的应用(v2)按从小到大,方便点为1的应用(v1)按从大到小排序。贪心,先将v2中的内存和累加,再遍历一遍,每当内存和大于等于m更新一次ans的值,再每次舍弃v2中最小的,去取v1中最大的,因为这样操作能使内存和尽可能的大于或接近m,我们就可以尽可能的少删除应用从而使得失去的方便点尽可能少。
while(t--) {
		int n,m; cin >> n >> m;
		ll sum=0;
		for(int i=1;i<=n;i++) cin >> a[i],sum+=a[i];
		for(int i=1;i<=n;i++) cin >> b[i];
		if(sum<m) 
		{
			cout << "-1" << endl;
			continue;
		}
		vector<int>v1,v2;
		for(int i=1;i<=n;i++) 
		{
			if(b[i]==1) v1.push_back(a[i]);
			else v2.push_back(a[i]);
		}
		sort(v1.begin(),v1.end(),greater<int>());//方便点为1的按照内存从大到小排列 
		sort(v2.begin(),v2.end());//方便点为2的按照从小到大 
		ll s=0;
		for(auto i : v2) s+=i;//方便点为2的内存和 
		int tmp=0,ans=INF;
		for(int i=0;i<=v2.size();i++)
		{
			while(tmp<v1.size()&&s<m) s+=v1[tmp],tmp++;//tmp代表选择了多少个方便点为1的应用
			if(s>=m) ans=min(ans,(int)(v2.size()-i)*2+tmp);//v2.size()-i代表此时选择了多少个方便点为2的应用
			if(i<v2.size()) s-=v2[i];
		}
		cout << ans << endl;
	}

E:有n个数,第i个数值为ai,取k个数,要求和最大,问最多有多少中情况。
思路:贪心,从大到小排序,选前k个,看最小值有几个,求组合数。因为数据很小,可以用杨辉三角也可以用lucas。我们在取的时候比较一下当前这个数有多少个与它相等的数,记为cnt,将cnt与k比较,如果cnt<=k,那么就只有一种情况,全选,然后更新k值,k=k-cnt,继续遍历。如果cnt>k,那就说明有多种取法,即组合数C(cnt,k)。下面附上杨辉三角解法。
int main()
{
    cin >> t;
    comb[0][0] = 1;
    for (int i = 1; i <= 1010; i++)
    {
        comb[i][0] = 1;
        for (int j = 1; j <= i; j++)
            comb[i][j] = (comb[i - 1][j] + comb[i - 1][j - 1]) % MODNUM;//MODNUM=1000000007
    }
    while(t--)
    {
        memset(rec, 0, sizeof(rec));
        int n, k;
        cin >> n >> k; 
        for (int j = 1; j <= n; j++)
        {
            int tmp; cin >> tmp;
            rec[tmp]++;
        }
        for (int j = n; j > 0; j--)
            if (rec[j] < k)
                k -= rec[j];
            else
            {
                cout << comb[rec[j]][k] << endl;
                break;
            }
    }
    return 0;
}