试题A:艺术与篮球(AC)
题解代码:(答案为3228)
#include<bits/stdc++.h>
using namespace std;
int cnt[10]={13,1,2,3,5,4,4,2,2,2};
int leapyear(int year){
if((year%400==0)||(year%4==0&&year%100!=0)){
return 1;
}
else return 0;
}
int maxday(int year,int month){
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) return 31;
else if(month==4||month==6||month==9||month==11) return 30;
else if(leapyear(year)) return 29;
else return 28;
}
int main(){
int basketball=0;
int year=2000,month=1,day=1;
int sum=0;
while(1){
sum+=cnt[year%10]+cnt[year/10%10]+cnt[year/100%10]+cnt[year/1000%10]; //年
sum+=cnt[month%10]+cnt[month/10%10]; //月
sum+=cnt[day%10]+cnt[day/10%10]; //日
if(sum>50){
basketball++;
}
if(year==2024&&month==4&&day==13) break;
else{
if(day<maxday(year,month)){
day++;
}
else if(month!=12){
month++;
day=1;
}
else{
year++;
month=1;
day=1;
}
}
sum=0;
}
cout<<basketball;
return 0;
}
试题B:五子棋对弈(AC)
题解代码:(答案为3126376)
#include<bits/stdc++.h>
using namespace std;
int a[6][6];
int ans=0;
void dfs(int n1,int n2,int id,int c) //白棋个数,黑棋个数,当前格子序号,当前格子颜色
{
if(n1>13||n2>12||id>=25) return;
int x=id/5,y=id%5;
a[x][y]=c;
if(y==4){ //检查当前行
int flag=0;
for(int i=1;i<=4;i++){
if(a[x][i]!=a[x][0]) flag=1;
}
if(flag==0) return;
}
if(x==4){ //检查当前列
int flag=0;
for(int i=1;i<=4;i++){
if(a[i][y]!=a[0][y]) flag=1;
}
if(flag==0) return;
}
if(id==20){ //检查右上到左下对角线
int flag=0;
for(int i=1;i<=4;i++){
if(a[i][4-i]!=a[0][4]) flag=1;
}
if(flag==0) return;
}
if(id==24){ //检查左上到右下对角线
int flag=0;
for(int i=1;i<=4;i++){
if(a[i][i]!=a[0][0]) flag=1;
}
if(flag==0) return;
}
if(id==24){ //顺利通过以上检查并且棋盘下满时,平局数加一
ans++;
return;
}
dfs(n1+1,n2,id+1,1); //下一个格子放白棋
dfs(n1,n2+1,id+1,2); //下一个格子放黑棋
}
int main()
{
dfs(1,0,0,1); //枚举第一个格子放白棋的所有情况
dfs(0,1,0,2); //枚举第一个格子放黑棋的所有情况
cout<<ans;
return 0;
}
试题C:训练士兵(AC)
题解代码:
#include <bits/stdc++.h>
using namespace std;
struct Soldier{
long long p;
int c;
}soldier[100002];
bool cmp(Soldier a,Soldier b){
if(a.c==b.c) return (a.p<b.p);
return a.c<b.c;
}
long long presum[100002];//前缀和数组,存前i个士兵均单独训练的价格
int main() {
long long n,s;
cin>>n>>s;
for(long long i=1;i<=n;i++){
cin>>soldier[i].p>>soldier[i].c;
}
sort(soldier+1,soldier+n+1,cmp);
presum[0]=0;
for(long long i=1;i<=n;i++){
presum[i]=presum[i-1]+soldier[i].p;
}
long long i=1;
while(1){
if(s>(presum[n]-presum[i-1])) break;
i++;
}
long long result=0;
result+=s*soldier[i-1].c;
for(long long j=i;j<=n;j++){
result+=soldier[j].p*(soldier[j].c-soldier[i-1].c);
}
cout<<result;
return 0;
}
试题D:团建(AC)
题解代码:
#include <bits/stdc++.h>
using namespace std;
const int maxsize=2e5+10;
int n, m;
int c[maxsize], d[maxsize];
vector<int> neighbor1[maxsize], neighbor2[maxsize];
int search(int v,int u,int fa_v,int fa_u){
int ans=0;
map<int,int> son_v;
for(auto x:neighbor1[v]){
if(x!=fa_v){
son_v[c[x]]=x;
}
}
for(auto x:neighbor2[u]){
if(x!=fa_u){
if(son_v.count(d[x])){
ans=max(ans,search(son_v[d[x]],x, v, u));
}
}
}
return ans+1;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>c[i];
for(int i=1;i<=m;i++) cin>>d[i];
int u,v;
for(int i=1;i<n;i++){
cin>>u>>v;
neighbor1[u].push_back(v);
neighbor1[v].push_back(u);
}
for(int i=1;i<m;i++){
cin>>u>>v;
neighbor2[u].push_back(v);
neighbor2[v].push_back(u);
}
int ans=0;
if(c[1]==d[1]){
ans=search(1,1,0,0);
}
cout<<ans<<endl;
return 0;
}
试题E:成绩统计(AC)
题解代码:
#include<bits/stdc++.h>
#define N 100005
using namespace std;
int n,k,a[N];
double t,num[N],sq_pre[N],pre[N];
bool cmp(double x,double y){
return x<y;
}
bool testOK(int x){
for(int i=1;i<=x;i++)
num[i]=a[i];
sort(num+1,num+x+1,cmp);
for(int i=1;i<=x;i++){
pre[i]=pre[i-1]+num[i];
sq_pre[i]=sq_pre[i-1]+num[i]*num[i];
}
for(int begin=1;begin+k-1<=x;begin++)
if(sq_pre[begin+k-1]-sq_pre[begin-1]-(pre[begin+k-1]-pre[begin-1])*(pre[begin+k-1]-pre[begin-1])/k<k*(double)t)
return true;
return false;
}
int main(){
cin>>n>>k>>t;
if(k>n){
cout<<"-1";
return 0;
}
for(int i=1;i<=n;i++)
cin>>a[i];
int left=k,right=n,mid;
while(true){
if(left==right){
cout<<(testOK(left)?left:-1);
return 0;
}
mid=(left+right)/2;
if(testOK(mid))
right=mid;
else
left=mid+1;
}
}
试题F:因数计数(36分)
题解代码:
\\\\\\\
试题G:零食采购(27分)
题解代码:
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> adj; // 邻接表表示树
vector<int> c; // 每个星球的零食种类
vector<int> path; // 存储从起点到终点的路径
bool found = false; // 标记是否找到路径
// DFS查找从u到v的路径
void dfs(int u, int v, vector<int>& currentPath, vector<bool>& visited) {
visited[u] = true;
currentPath.push_back(u);
if (u == v) {
path = currentPath; // 找到路径
found = true;
return;
}
for (int neighbor : adj[u]) {
if (!visited[neighbor]) {
dfs(neighbor, v, currentPath, visited);
if (found) return; // 如果找到路径,直接返回
}
}
currentPath.pop_back(); // 回溯。由于是树,vis可以不用回溯
}
int main() {
int n, q;
cin >> n >> q;
adj.resize(n + 1);
c.resize(n + 1);
// 输入每个星球的零食种类
for (int i = 1; i <= n; i++) {
cin >> c[i];
}
// 输入n-1条边,构建树
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
// 处理每个查询
for (int i = 0; i < q; i++) {
int s, t;
cin >> s >> t;
// 初始化
path.clear();
found = false;
vector<bool> visited(n + 1, false);
vector<int> currentPath;
// 查找从s到t的路径
dfs(s, t, currentPath, visited);
// 统计路径上的零食种类
set<int> kinds;
for (int node : path) {
kinds.insert(c[node]);
}
// 输出结果
cout << kinds.size() << endl;
}
return 0;
}