题意:两个人各选择了n个答案(T或F),第二个人的答案有k个是对的,找出第一个人答案正确的最大数量。
题记:分为两种情况,两个人选的答案相同,那么第二个人正确则第一个人也正确。两个人选的答案不同,第二个人答案错误第一个人则正确。
#include
using namespace std;
int main(){
int k;
cin>>k;
string s1,s2;
cin>>s1>>s2;
int a=0,b=0,ans=0;
for(int i=0;i<s1.size();i++){
if((s1[i]=='T'&&s2[i]=='T')||(s1[i]=='F'&&s2[i]=='F'))
a++;
else
b++;
}
if(k<=a) ans=k+b;
else ans=a+b-(k-a);
cout<<ans<<endl;
return 0;
}
题意:莫比乌斯反演模板题。
题记:略
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
const int N = 1e7+2;
const int mod = 1e9 + 7;
const int MAXN = 1e7+2;
bool check[MAXN + 10];
int prime[MAXN + 10];
int mu[MAXN + 10];
void Moblus()
{
memset(check, false, sizeof(check));
mu[1] = 1;
int tot = 0;
for (int i = 2; i <= MAXN; i++)
{
if (!check[i])
{
prime[tot++] = i;
mu[i] = -1;
}
for (int j = 0; j < tot; j++)
{
if (i * prime[j] > MAXN) break;
check[i * prime[j]] = true;
if (i % prime[j] == 0)
{
mu[i * prime[j]] = 0;
break;
}
else
{
mu[i * prime[j]] = -mu[i];
}
}
}
}
int sum[MAXN + 10];
//找[1,n],[1,m]内互质的数的对数
long long solve(int n, int m)
{
long long ans = 0;
if (n > m)swap(n, m);
for (int i = 1, la = 0; i <= n; i = la + 1)
{
la = min(n / (n / i), m / (m / i));
ans += (long long)(sum[la] - sum[i - 1]) * (n / i) * (m / i);
}
return ans;
}
int main()
{
Moblus();
sum[0] = 0;
for (int i = 1; i <= MAXN; i++)
sum[i] = sum[i - 1] + mu[i];
int a, b, c, d, k;
int T;
scanf("%d%d%d%d", &a, &b, &c, &d);
long long ans = solve(b, d) - solve((a - 1), d) - solve(b , (c - 1))
+ solve((a - 1), (c - 1));
printf("%lld\n", ans);
return 0;
}
题意:找出k个不同难度的题为一个方案,问有多少个方案。
题记:用dp来做,dp[i][j]表示的是前i种数选j个的方案数,由于每次循环只用到i-1的方案数,可以用滚动数组优化。
#include
using namespace std;
typedef long long ll;
const int N=1010,MOD=998244353;
ll dp[N];
map<int,int>mp;
int main(){
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++){
int x;
cin>>x;
mp[x]++;
}
map<int,int>::iterator it=mp.begin();
int sz=mp.size();
dp[0]=1;
for(int i=1;i<=sz;i++){
for(int j=k;j>=1;j--)
dp[j]=(dp[j-1]*(it->second)+dp[j])%MOD;
it++;
}
cout<<dp[k]<<endl;
return 0;
}
题意:给出屋子的两个对称坐标的和羊的坐标,求羊在不碰到屋子的情况下羊绳最长的长度。
题记:先把屋子画为一个矩形,分为两种情况,一种是羊到矩形的边距离最短,一种是羊到矩形的点距离最短。
#include
using namespace std;
double cal(double x1, double y1, double x2, double y2)
{
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
int main(){
double ans;
double x, y, x1, x2, y2, y1;
cin >> x >> y >> x1 >> y1 >> x2 >> y2;
if (x >= min(x1, x2) && x <= max(x2, x1))
ans = min(abs(y1 - y), abs(y2 - y));
else if (y >= min(y1, y2) && y <= max(y1, y2))
ans = min(abs(x - x1), abs(x - x2));
else
ans = min(cal(x, y, x1, y1), min(cal(x, y, x2, y2), min(cal(x, y, x1, y2), cal(x, y, x2, y1))));
printf("%.3f\n",ans);
return 0;
}
题意:给出一个x,分解x为一对质数(两个质数相加等于x),如果有多对,取差值最大的一对。取这两个数的差值继续做上面的操作,直到x小于4。
题记:打表素数,然后对于遍历素数,判断x-当前素数是否素数即可。
#include
using namespace std;
const int N=1e6;
bool vis[N+10];
int primes[N],cnt;
//朴素筛法
/*
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (vis[i]) continue;
primes[cnt ++ ] = i;
for (int j = i + i; j <= n; j += i)
vis[j] = true;
}
}
*/
//线性筛法
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!vis[i]) primes[cnt ++ ] = i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
vis[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
int main(){
get_primes(N);
int x;
cin>>x;
int ans=0;
while(x>=4){
for(int i=0;i<cnt;i++){
if(vis[x-primes[i]]==false){
//cout<
x=x-primes[i]-primes[i];
ans++;
break;
}
}
//cout<
}
cout<<ans<<endl;
return 0;
}
题意:给出n个时间(毫秒 )和s倍,求以整数秒限制的t。
题记:找出最大的时间,乘上s然后向上取整即可。
#include
using namespace std;
typedef long long ll;
const int N=110;
int a[N];
int main(){
int n,s;
cin>>n>>s;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
cout<<(a[n-1]*s+999)/1000<<endl;
return 0;
}
剩下题目待补。。。