啥也不说了,直接看........题解。
A题:a+b
是个人就能过~
B题:排序
N就1000,你想咋排就咋排
#include<cstdio>
#include<algorithm>
using namespace std;
const int M=1024;
int a[M];
int main(){
int t,n;
while(~scanf("%d",&t)){
while(t--){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n);
for(int i=0;i<n;i++){
printf("%d%c",a[i],i==n-1?'\n':' ');
}
}
}
return 0;
}
C题:二进制枚举
题目看着好像很厉害的样子,其实一看数据量,披萨上能放的东西的种类是16种。
对于披萨,这些东西就放或不放两种状态,总状态共2^16种,枚举这些状态,然后验证状态是否满足所有人的要求就可以了。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define M 10000
struct request {
int want;
int dont;
} req[M];
int len=0;
char result[M][100];
int cnt=0;
int input() {
int j,want,dont;
char str[100]= {0};
len=0;
while(gets(str)) {
want=0;
dont=0;
if(str[0]=='.') return 1;
for(j=0; str[j]!= ';' ; j+=2)
if(str[j]=='+')
want|= (1<<(str[j+1]-'A'));
else
dont|= (1<<(str[j+1]-'A'));
req[len].want = want;
req[len].dont = dont;
len++;
}
return 0;
}
int solve() {
int state,j,i,x=0;
char str[100]= {0};
for(state=0; state<(1<<16); state++) {
for(j=0; j<len; j++)
if( (state&req[j].want) || ( (~state)&req[j].dont) )
continue;
else
break;
if(j==len) {
strcpy(result[cnt], "Toppings: ");
for(i=0; i<16; i++)
if( state& (1<<i) )
str[x++] = 'A'+i;
str[x]=0;
strcat(result[cnt], str);
cnt++;
return 1;
}
}
strcpy(result[cnt],"No pizza can satisfy these requests.");
cnt++;
return 0;
}
void output() {
int i;
for(i=0; i<cnt; i++)
printf("%s\n",result[i]);
}
int main() {
int res=0;
while(1) {
res = input();
if(!res) break;
solve();
}
output();
return 0;
}
D题:BFS
vincent找的宽搜入门题,还是不错滴
#include<cstdio>
#include<cstring>
#include<queue>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
const int M=1e5+10;
bool vis[M];
int n,k;
struct Q{
int id,step;
}now,pre;
queue<Q> q;
void solve(int x){
if(x<0||x>1e5||vis[x]) return ;
vis[x]=true;
now.id=x;
now.step=pre.step+1;
q.push(now);
}
int bfs(){
vis[n]=true;
now.id=n;
now.step=0;
while(!q.empty()) q.pop();
q.push(now);
while(!q.empty()){
pre=q.front();
q.pop();
if(pre.id==k) return pre.step;
solve(pre.id+1);
solve(pre.id-1);
solve(pre.id*2);
}
}
int main(){
while(~scanf("%d%d",&n,&k)){
mt(vis,0);
printf("%d\n",bfs());
}
return 0;
}
E题:模拟
求给出的日期范围内素数月素数日的个数。
对于一般的日期模拟的题目,给一个笨笨的好方法,那就是一天一天的去模拟、去判断,因为一般日期范围都不会太大,写出的代码虽然丑,但是有保障,好调试。
本题就是这样,判断区间内每一天是否为素数月素数日。
注意闰年的影响。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int x[110];
int noleap[]= {0,0,9,11,0,11,0,11,0,0,0,10,0};//noLeap
int leap[]= {0,0,10,11,0,11,0,11,0,0,0,10,0};//Leap
int a1[]={0,31,29,31,30,31,30,31,31,30,31,30,31};//Leap
int a2[]={0,31,28,31,30,31,30,31,31,30,31,30,31};//noLeap
bool isleap(int y){//判断是否为闰年
if((y%4==0&&y%100!=0)||y%400==0){
return true;
}
else return false;
}
void isprime(){//筛素数
memset(x,1,sizeof(x));
x[0]=0;
x[1]=0;
for(int i=2;i<=sqrt(100)+1;i++){
if(!x[i]) continue;
for(int j=(i<<1);j<=100;j+=i){
x[j]=0;
}
}
}
int main(){
isprime();
int n,y1,m1,d1,y2,m2,d2;
int ans;
int i,j,k;
while(~scanf("%d",&n)){
while(n--){
ans=0;
scanf("%d%d%d%d%d%d",&y1,&m1,&d1,&y2,&m2,&d2);
i=y1;//年
j=m1;//月
k=d1;//日
while(1){
if(i==y2&&j==m2&&k==d2) break;
if(isleap(i)){
if(x[j]){
if(x[k]){
ans++;
}
}
if(k==a1[j]){
j++;
k=1;
}
else{
k++;
}
}
else{
if(x[j]){
if(x[k]){
ans++;
}
}
if(k==a2[j]){
j++;
k=1;
}
else{
k++;
}
}
if(j>12){
i++;
j=1;
k=1;
}
}
if(x[m2]&&x[d2]) ans++;//判断最后一天
printf("%d\n",ans);
}
}
return 0;
}
F题:进制转换
求出a*b=c是哪个进制下的转换
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int trans(int t,int b) {
int k = 1;
int ret = 0;
while (t>0) {
ret += (t%10)*k;
t /= 10;
k *= b;
}
return ret;
}
int main() {
int Cas,minn,k,p,q,r;
int a,b,c;
scanf("%d",&Cas);
while (Cas--) {
scanf("%d%d%d",&p,&q,&r);
a = p;
b = q;
c = r;
minn = 0;
while (a>0) {
if (minn<a%10) minn = a%10;
a /= 10;
}
while (b>0) {
if (minn<b%10) minn = b%10;
b /= 10;
}
while (c>0) {
if (minn<c%10) minn = c%10;
c /= 10;
}
int i;
for (i=minn+1; i<=16; i++) {
a = trans(p,i);
b = trans(q,i);
c = trans(r,i);
if (a*b == c) break;
}
if (i == 17) i = 0;
printf("%d\n",i);
}
return 0;
}
G题:由于此题需要另一题的背景,不做,略过。
H题:高精度
#include<iostream>
#include<string>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
const int M = 500;
int a[M];
int b[M];
char s1[M],s2[M];
int main() {
int Cas,i,time=1;
scanf("%d",&Cas);
while(Cas--) {
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
scanf("%s%s",s1,s2);
int len1=strlen(s1);
int len2=strlen(s2);
for(i=len1-1; i>=0; i--) {
a[len1-1-i]=(int)(s1[i]-'0');
}
for(i=len2-1; i>=0; i--) {
b[len2-1-i]=(int)(s2[i]-'0');
}
int maxlen;
if(len1>len2) maxlen = len1;
else maxlen = len2;
for(i=0; i<=maxlen+100; i++) {
a[i]=a[i]+b[i];
while(a[i]>1) {
a[i+1]++;
a[i]-=2;
}
}
for(i=maxlen+100; i>=0; i--) {
if(a[i]) break;
}
printf("%d ",time);
if(i==-1&&a[0]==0){
printf("0");
}
else {
for(; i>=0; i--) {
printf("%d",a[i]);
}
}
puts("");
time++;
}
return 0;
}
I题:栈贪心模拟
给出城市的正视图,所有的大楼都是矩形,给出每个高度改变时的坐标,问最少可以看出有几个大楼。
可以看出,w和横坐标是没有用的。。。
用栈模拟,先将0压栈,然后遍历n个数,设当前高度为y,如果栈顶元素大于y的话,说明栈顶元素所代表的高度的楼找到了,就不断弹出栈顶元素并ans+1直到栈顶元素小于等于y,如果此时栈顶元素小于y的话,就将y压栈,否则continue。
#include<iostream>
#include<cmath>
#include<cstring>
#include<stack>
#include<cstdio>
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define E exp(double(1))
#define eps 1e-7
using namespace std;
#ifdef __LL64
typedef __LL64 LL;
#else
typedef long long LL;
#endif
const int MAXN = 60000;
int x,y[MAXN];
int main() {
int n,w;
while(~scanf("%d%d",&n,&w)) {
for(int i=0; i<n; i++) {
scanf("%d%d",&x,&y[i]);
}
y[n]=0;
stack<int> st;
int ans = 0;
st.push(0);
for(int i=0; i<=n; i++) {
while(st.top()>y[i] && !st.empty()) {
st.pop();
ans++;
}
if(y[i]!=st.top()) {
st.push(y[i]);
}
}
printf("%d\n",ans);
}
return 0;
}
J题:二分
这是道被各种数据结构和算法碾压过的题,可以用二分、哈希、map、字典树这些玩意儿一一碾压过去。
这里讨论二分的做法,首先给字符串排个序,然后输入一个,就进行二分查找。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int k;
struct Dictionary{
char s1[12];
char s2[12];
}d[100100];
bool cmp(Dictionary A,Dictionary B){
if(strcmp(A.s2,B.s2) == 1) return false;
return true;
}
void binarySearch(char str[]){
int L = 0;
int R = k-1;
while(L<=R){
int mid = (L+R)>>1;
if(!strcmp(d[mid].s2,str)){
puts(d[mid].s1);
return;
}
if(~strcmp(d[mid].s2,str)) R = mid - 1;
else L = mid + 1;
}
puts("eh");
return;
}
int main(){
k = 0;
char tmp;
while(1){
tmp = getchar();
if(tmp == '\n') break;
d[k].s1[0] = tmp;
scanf("%s%s",d[k].s1+1,d[k].s2);
k++;
tmp = getchar();
}
sort(d,d+k,cmp);
// for(int i=0;i<k;i++){
// printf("%s---%s\n",d[i].s1,d[i].s2);
// }
char str[12];
while(~scanf("%s",str)){
binarySearch(str);
}
return 0;
}