T1
大水题,不解释 上考场代码#include <algorithm>
#include <cstdio>
using namespace std;
int main() {
freopen("pencil.in","r",stdin);
freopen("pencil.out","w",stdout);
int n,Min = 0x7fffffff;
scanf("%d",&n);
for (int i = 1;i <= 3;i++) {
int number,money,count;
scanf("%d%d",&number,&money);
count = n/number;
if (n%number) count++; //count为需要买的包数
Min = min(Min,count*money); //取最小的
}
printf("%d",Min);
return 0;
}
T2
简单的模拟,生成date1到date2的所有日期,判断是否回文上考场代码
#include <cstdio>
int m[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
inline bool check(int date) { //判断是否回文
int t[9];
t[0] = 0;
while (date) {
t[++t[0]] = date%10;
date /= 10;
}
for (int i = 1;i <= 4;i++)
if (t[i] != t[8-i+1]) return false;
return true;
}
inline int next(int i) { //生成下一个日期
int year,month,day;
day = (i%10)+((i/10%10)*10); //取出日
i /= 100;
month = (i%10)+((i/10%10)*10); //取出月
i /= 100;
year = (i%10)+((i/10%10)*10)+((i/100%10)*100)+i/1000*1000; //取出年
if ((!(year%4) && year%100) || !(year%400)) m[2] = 29; //判断是否为闰年
day++; //下一天
if (day == m[month]+1) { //若到了月底,则变到下一月
day = 1;
month++;
}
if (month == 13) { //若到了年底,则变到下一年
month = 1;
year++;
}
return day+month*100+year*10000; //把年月日变成8位数字
}
int main() {
freopen("date.in","r",stdin);
freopen("date.out","w",stdout);
int date1,date2,ans = 0;
scanf("%d%d",&date1,&date2);
for (int i = date1;i <= date2;i = next(i)) //生成date1到date2的所有日期
if (check(i)) ans++; //判断是否回文
printf("%d",ans);
return 0;
}
T3
考场上写了个暴力模拟,70分......出来后发现还是可以做的,写个队列就行了,超出86400s的就出队70分考场代码#include <cstring>
#include <cstdio>
#include <map>
using namespace std;
int n,t[100001],k[100001];
bool tmp[100001];
map<int,int> x[100001];
int main() {
freopen("port.in","r",stdin);
freopen("port.out","w",stdout);
scanf("%d",&n);
for (int i = 1;i <= n;i++) {
scanf("%d%d",&t[i],&k[i]);
for (int j = 1;j <= k[i];j++) scanf("%d",&x[i][j]);
int L = 1,R = i,pos = i;
while (L <= R) {
int mid = (L+R)>>1;
if (t[mid] > t[i]-86400) {
pos = mid;
R = mid-1;
} else L = mid+1;
}
int ans = 0;
memset(tmp,false,sizeof(tmp));
for (int j = pos;j <= i;j++)
for (int l = 1;l <= k[j];l++)
if (!tmp[x[j][l]]) {
ans++;
tmp[x[j][l]] = true;
}
printf("%d\n",ans);
}
return 0;
}
100分代码
#include <cstdio>
#include <queue>
#include <map>
using namespace std;
int n,ans = 0,vis[100001];
struct Queue { int t,x; };
queue<Queue> Q;
inline int read(int &x) { //读入优化
char ch;
while ((ch = getchar()) < '0' || ch > '9');
x = ch-'0';
while ((ch = getchar()) >= '0' && ch <= '9') x = x*10+ch-'0';
}
int main() {
freopen("port.in","r",stdin);
freopen("port.out","w",stdout);
read(n);
for (int i = 1;i <= n;i++) {
int t,k;
read(t),read(k);
for (int i = 1,x;i <= k;i++) {
read(x);
if (!vis[x]) ans++; //若这个乘客是其他国籍,则统计
vis[x]++; //统计
Q.push((Queue){t,x}); //加入队列
}
while (true) { //把86400以外的排除
Queue head = Q.front();
if (t-86400+1 <= head.t && head.t <= t) break;
else {
vis[head.x]--;
if (!vis[head.x]) ans--;
Q.pop();
}
}
printf("%d\n",ans);
}
return 0;
}
T4
考场上想不出,于是打了个暴力,40分......40分考场暴力代码#include <cstdio>
int main() {
int n,m,x[40001],ans[40001][4];
scanf("%d%d",&n,&m);
for (int i = 1;i <= m;i++) scanf("%d",&x[i]);
for (int a = 1;a <= m;a++)
for (int b = 1;b <= m;b++)
if (a != b)
for (int c = 1;c <= m;c++)
if (c != a && c != b && (double)x[b]-(double)x[a] < (double)((double)x[c]-(double)x[b])/3.0)
for (int d = 1;d <= m;d++)
if (d != a && d != b && d != c && x[a] < x[b] && x[b] < x[c] && x[c] < x[d] && x[b]-x[a] == 2*(x[d]-x[c])) {
ans[a][0]++;
ans[b][1]++;
ans[c][2]++;
ans[d][3]++;
}
for (int i = 1;i <= m;i++) printf("%d %d %d %d\n",ans[i][0],ans[i][1],ans[i][2],ans[i][3]);
return 0;
}
4重循环是用不到n的,没有白给的条件,没有没用的数据!!!我们可以把这4个数看作是个数轴上的点,根据题目给的条件,可知AB=2*CD,BC>6*CD,AD>9*CD那么,我们只需要确定D,就可以确定C点,然后再找AB。我们也可以通过找C来确定ABD。100分代码
#include <cstdio>
int n,m,x[40001],vis[15001],a[15001],b[15001],c[15001],d[15001];
int main() {
freopen("magic.in","r",stdin);
freopen("magic.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i = 1;i <= m;i++) {
scanf("%d",&x[i]);
vis[x[i]]++; //把所有数记在数轴上
}
for (int i = 1;i <= n/9;i++) { //枚举CD的长度
int sum = 0;
for (int j = i*9+2;j <= n;j++) {
sum += vis[j-(9*i+1)]*vis[j-(9*i+1)+2*i];
d[j] += sum*vis[j-i];
c[j-i] += sum*vis[j];
}
sum = 0;
for (int j = n-(9*i+1);j >= 1;j--) { //枚举CD两点,确定AB的个数
sum += vis[j+(9*i+1)]*vis[j+(9*i+1)-i];
a[j] += sum*vis[j+2*i];
b[j+2*i] += sum*vis[j];
}
}
for (int i = 1;i <= m;i++) printf("%d %d %d %d\n",a[x[i]],b[x[i]],c[x[i]],d[x[i]]);
return 0;
}